Merge branch 'master' into matthew-carroll_renderbox-assertion-message-improvement
diff --git a/.ci.yaml b/.ci.yaml
index 527f3f7..78b22e1 100644
--- a/.ci.yaml
+++ b/.ci.yaml
@@ -80,7 +80,7 @@
device_type: none
$flutter/osx_sdk : >-
{
- "sdk_version": "14e222b"
+ "sdk_version": "14e300c"
}
mac_arm64:
properties:
@@ -93,7 +93,7 @@
cpu: arm64
$flutter/osx_sdk : >-
{
- "sdk_version": "14e222b"
+ "sdk_version": "14e300c"
}
mac_benchmark:
properties:
@@ -108,7 +108,7 @@
["devicelab", "hostonly", "mac"]
$flutter/osx_sdk : >-
{
- "sdk_version": "14e222b"
+ "sdk_version": "14e300c"
}
mac_x64:
properties:
@@ -121,7 +121,7 @@
cpu: x86
$flutter/osx_sdk : >-
{
- "sdk_version": "14e222b"
+ "sdk_version": "14e300c"
}
mac_build_test:
properties:
@@ -135,7 +135,7 @@
cpu: x86
$flutter/osx_sdk : >-
{
- "sdk_version": "14e222b"
+ "sdk_version": "14e300c"
}
mac_android:
properties:
@@ -170,7 +170,7 @@
device_os: iOS-16
$flutter/osx_sdk : >-
{
- "sdk_version": "14e222b"
+ "sdk_version": "14e300c"
}
mac_arm64_ios:
properties:
@@ -184,7 +184,7 @@
device_os: iOS-16
$flutter/osx_sdk : >-
{
- "sdk_version": "14e222b"
+ "sdk_version": "14e300c"
}
windows:
properties:
@@ -262,7 +262,8 @@
dependencies: >-
[
{"dependency": "android_sdk", "version": "version:33v6"},
- {"dependency": "android_virtual_device", "version": "33"}
+ {"dependency": "android_virtual_device", "version": "33"},
+ {"dependency": "open_jdk", "version": "version:11"}
]
tags: >
["framework","hostonly","linux"]
@@ -295,7 +296,7 @@
[
{"dependency": "android_sdk", "version": "version:33v6"},
{"dependency": "chrome_and_driver", "version": "version:114.0"},
- {"dependency": "open_jdk", "version": "version:11"},
+ {"dependency": "open_jdk", "version": "version:17"},
{"dependency": "goldctl", "version": "git_revision:f808dcff91b221ae313e540c09d79696cd08b8de"},
{"dependency": "clang", "version": "git_revision:5d5aba78dbbee75508f01bcaa69aedb2ab79065a"},
{"dependency": "cmake", "version": "build_id:8787856497187628321"},
@@ -314,7 +315,7 @@
[
{"dependency": "android_sdk", "version": "version:33v6"},
{"dependency": "chrome_and_driver", "version": "version:114.0"},
- {"dependency": "open_jdk", "version": "version:11"},
+ {"dependency": "open_jdk", "version": "version:17"},
{"dependency": "goldctl", "version": "git_revision:f808dcff91b221ae313e540c09d79696cd08b8de"},
{"dependency": "clang", "version": "git_revision:5d5aba78dbbee75508f01bcaa69aedb2ab79065a"},
{"dependency": "cmake", "version": "build_id:8787856497187628321"},
@@ -411,20 +412,20 @@
- .ci.yaml
- name: Linux firebase_oriol33_abstract_method_smoke_test
- bringup: true
recipe: firebaselab/firebaselab
timeout: 60
properties:
dependencies: >-
[
- {"dependency": "android_sdk", "version": "version:33v6"}
+ {"dependency": "android_sdk", "version": "version:33v6"},
+ {"dependency": "open_jdk", "version": "version:11"}
]
tags: >
["firebaselab"]
task_name: abstract_method_smoke_test
physical_devices: >-
["--device", "model=oriole,version=33"]
- virtual_device: >-
+ virtual_devices: >-
[]
- name: Linux firebase_abstract_method_smoke_test
@@ -434,11 +435,28 @@
properties:
dependencies: >-
[
- {"dependency": "android_sdk", "version": "version:33v6"}
+ {"dependency": "android_sdk", "version": "version:33v6"},
+ {"dependency": "open_jdk", "version": "version:11"}
]
tags: >
["firebaselab"]
task_name: abstract_method_smoke_test
+ physical_devices: >-
+ [
+ "--device", "model=redfin,version=30",
+ "--device", "model=griffin,version=24"
+ ]
+ # TODO(flutter/flutter#123331): This device is flaking.
+ # "--device", "model=Nexus6P,version=25",
+ virtual_devices: >-
+ [
+ "--device", "model=Nexus5,version=21",
+ "--device", "model=Nexus5,version=22",
+ "--device", "model=Nexus5,version=23",
+ "--device", "model=Nexus6P,version=26",
+ "--device", "model=Nexus6P,version=27",
+ "--device", "model=NexusLowRes,version=29"
+ ]
- name: Linux firebase_android_embedding_v2_smoke_test
recipe: firebaselab/firebaselab
@@ -446,11 +464,28 @@
properties:
dependencies: >-
[
- {"dependency": "android_sdk", "version": "version:33v6"}
+ {"dependency": "android_sdk", "version": "version:33v6"},
+ {"dependency": "open_jdk", "version": "version:11"}
]
tags: >
["firebaselab"]
task_name: android_embedding_v2_smoke_test
+ physical_devices: >-
+ [
+ "--device", "model=redfin,version=30",
+ "--device", "model=griffin,version=24"
+ ]
+ # TODO(flutter/flutter#123331): This device is flaking.
+ # "--device", "model=Nexus6P,version=25",
+ virtual_devices: >-
+ [
+ "--device", "model=Nexus5,version=21",
+ "--device", "model=Nexus5,version=22",
+ "--device", "model=Nexus5,version=23",
+ "--device", "model=Nexus6P,version=26",
+ "--device", "model=Nexus6P,version=27",
+ "--device", "model=NexusLowRes,version=29"
+ ]
- name: Linux firebase_release_smoke_test
recipe: firebaselab/firebaselab
@@ -458,11 +493,28 @@
properties:
dependencies: >-
[
- {"dependency": "android_sdk", "version": "version:33v6"}
+ {"dependency": "android_sdk", "version": "version:33v6"},
+ {"dependency": "open_jdk", "version": "version:11"}
]
tags: >
["firebaselab"]
task_name: release_smoke_test
+ physical_devices: >-
+ [
+ "--device", "model=redfin,version=30",
+ "--device", "model=griffin,version=24"
+ ]
+ # TODO(flutter/flutter#123331): This device is flaking.
+ # "--device", "model=Nexus6P,version=25",
+ virtual_devices: >-
+ [
+ "--device", "model=Nexus5,version=21",
+ "--device", "model=Nexus5,version=22",
+ "--device", "model=Nexus5,version=23",
+ "--device", "model=Nexus6P,version=26",
+ "--device", "model=Nexus6P,version=27",
+ "--device", "model=NexusLowRes,version=29"
+ ]
- name: Linux flutter_packaging_test
recipe: packaging/packaging
@@ -556,6 +608,7 @@
["framework", "hostonly", "shard", "linux"]
runIf:
- dev/**
+ - examples/api/**
- packages/flutter/**
- packages/flutter_driver/**
- packages/integration_test/**
@@ -1041,6 +1094,7 @@
- name: Linux web_benchmarks_html
recipe: devicelab/devicelab_drone
+ presubmit: false
timeout: 60
properties:
dependencies: >-
@@ -1056,6 +1110,25 @@
- bin/**
- .ci.yaml
+ - name: Linux web_benchmarks_skwasm
+ bringup: true
+ recipe: devicelab/devicelab_drone
+ presubmit: false
+ timeout: 60
+ properties:
+ dependencies: >-
+ [
+ {"dependency": "android_sdk", "version": "version:33v6"},
+ {"dependency": "chrome_and_driver", "version": "version:114.0"}
+ ]
+ tags: >
+ ["devicelab"]
+ task_name: web_benchmarks_skwasm
+ runIf:
+ - dev/**
+ - bin/**
+ - .ci.yaml
+
- name: Linux web_long_running_tests_1_5
recipe: flutter/flutter_drone
timeout: 60
@@ -2330,6 +2403,26 @@
["devicelab", "android", "linux", "samsung", "s10"]
task_name: platform_views_scroll_perf__timeline_summary
+ - name: Linux_android platform_views_scroll_perf_impeller__timeline_summary
+ bringup: true
+ recipe: devicelab/devicelab_drone
+ presubmit: false
+ timeout: 60
+ properties:
+ tags: >
+ ["devicelab", "android", "linux"]
+ task_name: platform_views_scroll_perf_impeller__timeline_summary
+
+ - name: Linux_samsung_s10 platform_views_scroll_perf_impeller__timeline_summary
+ bringup: true
+ recipe: devicelab/devicelab_drone
+ presubmit: false
+ timeout: 60
+ properties:
+ tags: >
+ ["devicelab", "android", "linux", "samsung", "s10"]
+ task_name: platform_views_scroll_perf_impeller__timeline_summary
+
- name: Linux_android platform_view__start_up
recipe: devicelab/devicelab_drone
presubmit: false
@@ -2539,6 +2632,7 @@
["framework", "hostonly", "shard", "linux"]
runIf:
- dev/**
+ - examples/api/**
- packages/flutter/**
- packages/flutter_driver/**
- packages/integration_test/**
@@ -2572,6 +2666,7 @@
recipe: devicelab/devicelab_drone
timeout: 60
properties:
+ add_recipes_cq: "true"
dependencies: >-
[
{"dependency": "gems", "version": "v3.3.14"}
@@ -2626,7 +2721,7 @@
[
{"dependency": "android_sdk", "version": "version:33v6"},
{"dependency": "chrome_and_driver", "version": "version:114.0"},
- {"dependency": "open_jdk", "version": "version:11"},
+ {"dependency": "open_jdk", "version": "version:17"},
{"dependency": "gems", "version": "v3.3.14"},
{"dependency": "goldctl", "version": "git_revision:f808dcff91b221ae313e540c09d79696cd08b8de"}
]
@@ -2644,7 +2739,7 @@
[
{"dependency": "android_sdk", "version": "version:33v6"},
{"dependency": "chrome_and_driver", "version": "version:114.0"},
- {"dependency": "open_jdk", "version": "version:11"},
+ {"dependency": "open_jdk", "version": "version:17"},
{"dependency": "gems", "version": "v3.3.14"},
{"dependency": "goldctl", "version": "git_revision:f808dcff91b221ae313e540c09d79696cd08b8de"}
]
@@ -2662,7 +2757,7 @@
[
{"dependency": "android_sdk", "version": "version:33v6"},
{"dependency": "chrome_and_driver", "version": "version:114.0"},
- {"dependency": "open_jdk", "version": "version:11"},
+ {"dependency": "open_jdk", "version": "version:17"},
{"dependency": "gems", "version": "v3.3.14"},
{"dependency": "goldctl", "version": "git_revision:f808dcff91b221ae313e540c09d79696cd08b8de"}
]
@@ -2817,6 +2912,7 @@
["framework", "hostonly", "shard", "mac"]
runIf:
- dev/**
+ - examples/api/**
- packages/flutter/**
- packages/flutter_driver/**
- packages/integration_test/**
@@ -4065,7 +4161,7 @@
[
{"dependency": "android_sdk", "version": "version:33v6"},
{"dependency": "chrome_and_driver", "version": "version:114.0"},
- {"dependency": "open_jdk", "version": "version:11"},
+ {"dependency": "open_jdk", "version": "version:17"},
{"dependency": "goldctl", "version": "git_revision:f808dcff91b221ae313e540c09d79696cd08b8de"},
{"dependency": "vs_build", "version": "version:vs2019"}
]
@@ -4083,7 +4179,7 @@
[
{"dependency": "android_sdk", "version": "version:33v6"},
{"dependency": "chrome_and_driver", "version": "version:114.0"},
- {"dependency": "open_jdk", "version": "version:11"},
+ {"dependency": "open_jdk", "version": "version:17"},
{"dependency": "goldctl", "version": "git_revision:f808dcff91b221ae313e540c09d79696cd08b8de"},
{"dependency": "vs_build", "version": "version:vs2019"}
]
@@ -4101,7 +4197,7 @@
[
{"dependency": "android_sdk", "version": "version:33v6"},
{"dependency": "chrome_and_driver", "version": "version:114.0"},
- {"dependency": "open_jdk", "version": "version:11"},
+ {"dependency": "open_jdk", "version": "version:17"},
{"dependency": "goldctl", "version": "git_revision:f808dcff91b221ae313e540c09d79696cd08b8de"},
{"dependency": "vs_build", "version": "version:vs2019"}
]
@@ -4163,6 +4259,7 @@
["framework", "hostonly", "shard", "windows"]
runIf:
- dev/**
+ - examples/api/**
- packages/flutter/**
- packages/flutter_driver/**
- packages/integration_test/**
diff --git a/.github/ISSUE_TEMPLATE/4_performance_others.md b/.github/ISSUE_TEMPLATE/4_performance_others.md
index 748786a..6777d05 100644
--- a/.github/ISSUE_TEMPLATE/4_performance_others.md
+++ b/.github/ISSUE_TEMPLATE/4_performance_others.md
@@ -1,8 +1,8 @@
---
-name: My app has some non-speed performance issues.
+name: My app has some non-speed performance issues
about: You are writing an application but have discovered that it uses too much memory, too much energy (e.g., CPU/GPU usage is high), or its app size is too large.
title: ''
-labels: 'created via performance template'
+labels: 'from: performance template'
assignees: ''
---
diff --git a/.github/ISSUE_TEMPLATE/5_performance_speed.md b/.github/ISSUE_TEMPLATE/5_performance_speed.md
index ba7f317..0c7054c 100644
--- a/.github/ISSUE_TEMPLATE/5_performance_speed.md
+++ b/.github/ISSUE_TEMPLATE/5_performance_speed.md
@@ -1,9 +1,9 @@
---
-name: My app is slow or missing frames.
+name: My app is slow or missing frames
about: You are writing an application but have discovered that it is slow, you are
not hitting 60Hz, or you are getting jank (missed frames).
title: ''
-labels: 'created via performance template'
+labels: 'from: performance template'
assignees: ''
---
diff --git a/.github/ISSUE_TEMPLATE/6_infrastructure.md b/.github/ISSUE_TEMPLATE/6_infrastructure.md
index 802371e..d12e41a 100644
--- a/.github/ISSUE_TEMPLATE/6_infrastructure.md
+++ b/.github/ISSUE_TEMPLATE/6_infrastructure.md
@@ -15,8 +15,8 @@
If you are filing a feature request, please describe the use case and a proposal.
- If you are requesting a small infra task with P0 or P1 priority, please add it to the
- "Infra Ticket Queue" project with "New" column, explain why the task is needed and what
- actions need to perform (if you happen to know). No need to set an assignee; the infra oncall
+ If you are requesting a small infra task with P0 priority, please add it to the
+ "Infra Ticket Queue" project with "New" column, explain why the task is urgent and what
+ actions need to be performed (if you happen to know). No need to set an assignee; the infra oncall
will triage and process the infra ticket queue.
-->
diff --git a/.github/ISSUE_TEMPLATE/7_cherry_pick.yml b/.github/ISSUE_TEMPLATE/7_cherry_pick.yml
index babf07c..8fd172a 100644
--- a/.github/ISSUE_TEMPLATE/7_cherry_pick.yml
+++ b/.github/ISSUE_TEMPLATE/7_cherry_pick.yml
@@ -1,4 +1,4 @@
-name: Request a cherry-pick.
+name: Request a cherry-pick
description: As a contributor, you would like to request that a feature be cherry-picked into a release.
title: '[CP] <title>'
labels: ['cp: review']
diff --git a/.github/ISSUE_TEMPLATE/8_design_doc.yml b/.github/ISSUE_TEMPLATE/8_design_doc.yml
new file mode 100644
index 0000000..76e4356
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/8_design_doc.yml
@@ -0,0 +1,32 @@
+name: Share a Flutter design document
+description: As a contributor, I would like to share a design document.
+labels: ['design doc']
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Thank you for your interest in contributing to Flutter!
+
+ Please ensure that you are following
+ https://github.com/flutter/flutter/wiki/Design-Documents
+ when sharing a design document.
+
+ Please fill out the sections below to the best of your ability.
+ - type: input
+ id: document_link
+ attributes:
+ label: Document Link
+ description: |
+ Insert the "https://flutter.dev/go" link for your document here.
+ For details on creating a link, see the instructions in
+ https://flutter.dev/go/template
+ validations:
+ required: true
+ - type: textarea
+ id: proposal_description
+ attributes:
+ label: What problem are you solving?
+ description: |
+ Please provide a brief description of the problem you are solving.
+ validations:
+ required: true
diff --git a/.github/ISSUE_TEMPLATE/9_first_party_packages.yml b/.github/ISSUE_TEMPLATE/9_first_party_packages.yml
new file mode 100644
index 0000000..0e8ef8a
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/9_first_party_packages.yml
@@ -0,0 +1,222 @@
+name: Report a bug in one of Flutter's first-party packages
+description: |
+ You found a bug in one of Flutter's first-party packages.
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Thank you for using Flutter!
+
+ If you are looking for support, please check out our documentation
+ or consider asking a question on Stack Overflow:
+
+ - https://flutter.dev/
+ - https://api.flutter.dev/
+ - https://stackoverflow.com/questions/tagged/flutter?sort=frequent
+ - type: checkboxes
+ attributes:
+ label: Is there an existing issue for this?
+ options:
+ - label: I have searched the [existing package issues](https://github.com/flutter/flutter/issues?q=is%3Aopen+is%3Aissue+label%3Apackage)
+ required: true
+ - label: I have read the [guide to filing a bug](https://flutter.dev/docs/resources/bug-reports)
+ required: true
+ - type: dropdown
+ id: packages
+ attributes:
+ label: What package does this bug report belong to?
+ description: |
+ If the package you are reporting a bug for is not listed here,
+ it could be a third party package's issue.
+ In that case, you should report the issue to the package's developers.
+ options:
+ - animations
+ - camera
+ - cross_file
+ - css_colors
+ - dynamic_layouts
+ - espresso
+ - extension_google_sign_in_as_googleapis_auth
+ - file_selector
+ - flutter_adaptive_scaffold
+ - flutter_image
+ - flutter_lints
+ - flutter_markdown
+ - flutter_migrate
+ - flutter_plugin_android_lifecycle
+ - flutter_template_images
+ - go_router
+ - go_router_builder
+ - google_identity_services_web
+ - google_maps_flutter
+ - google_sign_in
+ - image_picker
+ - in_app_purchase
+ - ios_platform_images
+ - local_auth
+ - metrics_center
+ - multicast_dns
+ - palette_generator
+ - path_provider
+ - pigeon
+ - plugin_platform_interface
+ - pointer_interceptor
+ - quick_actions
+ - rfw
+ - shared_preferences
+ - standard_message_codec
+ - url_launcher
+ - video_player
+ - web_benchmarks
+ - webview_flutter
+ - xdg_directories
+ validations:
+ required: true
+ - type: dropdown
+ id: target_platforms
+ attributes:
+ label: What target platforms are you seeing this bug on?
+ description: Have you confirmed that package supports the platform you are reporting against?
+ multiple: true
+ options:
+ - Android
+ - iOS
+ - Web
+ - macOS
+ - Linux
+ - Windows
+ validations:
+ required: true
+ - type: dropdown
+ id: pub_upgrade
+ attributes:
+ label: Have you already upgraded your packages?
+ description: |
+ Please check if the issue still persists or not after running `flutter pub upgrade`.
+ options:
+ - "Yes"
+ - "No"
+ validations:
+ required: true
+ - type: textarea
+ attributes:
+ label: Dependency versions
+ description: |
+ `pubspec.lock` file content that includes the package and its dependencies.
+
+ You can remove private dependencies from the file if they are sensitive.
+
+ If the file is too large to be uploaded to GitHub or the content is too long,
+ you may use online tools like https://pastebin.com and share the url here.
+
+ Note: Please do not upload screenshots of text. Instead, use code blocks
+ or the above mentioned ways to upload this.
+ value: |
+ <details><summary>pubspec.lock</summary>
+
+ ```lock
+ [Paste file content here]
+ ```
+
+ </details>
+ - type: textarea
+ attributes:
+ label: Steps to reproduce
+ description: Please tell us exactly how to reproduce the problem you are running into.
+ placeholder: |
+ 1. ...
+ 2. ...
+ 3. ...
+ validations:
+ required: true
+ - type: textarea
+ attributes:
+ label: Expected results
+ description: Please tell us what is expected to happen.
+ validations:
+ required: true
+ - type: textarea
+ attributes:
+ label: Actual results
+ description: Please tell us what is actually happening.
+ validations:
+ required: true
+ - type: textarea
+ attributes:
+ label: Code sample
+ description: |
+ Please create a minimal reproducible sample that shows the problem
+ and attach it below between the lines with the backticks.
+
+ To create it, use the `flutter create bug` command and update the `main.dart` file.
+
+ Alternatively, you can create a public GitHub repository to share your sample.
+
+ Without this we will unlikely be able to progress on the issue, and because of that
+ we regretfully will have to close it.
+
+ You can also refer to the package's example project if it is simple enough
+ to reproduce the bug.
+
+ Note: Please do not upload screenshots of text. Instead, use code blocks
+ or the above mentioned ways to upload your code sample.
+ value: |
+ <details><summary>Code sample</summary>
+
+ ```dart
+ [Paste your code here]
+ ```
+
+ </details>
+ validations:
+ required: true
+ - type: textarea
+ attributes:
+ label: Screenshots or Videos
+ description: |
+ Upload any screenshots or videos of the bug if applicable.
+ value: |
+ <details>
+ <summary>Screenshots / Video demonstration</summary>
+
+ [Upload media here]
+
+ </details>
+ - type: textarea
+ attributes:
+ label: Logs
+ description: |
+ Include the full logs of the commands you are running between the lines
+ with the backticks below. If you are running any `flutter` commands,
+ please include the output of running them with `--verbose`; for example,
+ the output of running `flutter --verbose create foo`.
+
+ If the logs are too large to be uploaded to GitHub, you may upload
+ them as a `txt` file or use online tools like https://pastebin.com to
+ share it.
+
+ Note: Please do not upload screenshots of text. Instead, use code blocks
+ or the above mentioned ways to upload logs.
+ value: |
+ <details><summary>Logs</summary>
+
+ ```console
+ [Paste your logs here]
+ ```
+
+ </details>
+ - type: textarea
+ attributes:
+ label: Flutter Doctor output
+ description: |
+ Please provide the full output of running `flutter doctor -v`
+ value: |
+ <details><summary>Doctor output</summary>
+
+ ```console
+ [Paste your output here]
+ ```
+
+ </details>
+ validations:
+ required: true
diff --git a/.github/autosubmit.yml b/.github/autosubmit.yml
deleted file mode 100644
index 74f6296..0000000
--- a/.github/autosubmit.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-# Copyright 2023 The Flutter Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file will be added to flutter's internal repository.
-# https://github.com/flutter/flutter/wiki/Autosubmit-bot
-config_path: 'autosubmit/flutter/autosubmit_master.yml'
diff --git a/.github/labeler.yml b/.github/labeler.yml
index 1599ae2..9571981 100644
--- a/.github/labeler.yml
+++ b/.github/labeler.yml
@@ -32,9 +32,6 @@
'd: examples':
- examples/**/*
-documentation:
- - examples/api/**/*
-
engine:
- bin/internal/engine.version
@@ -76,27 +73,16 @@
- packages/flutter_test/**/*
- packages/integration_test/**/*
-integration_test:
+'f: integration_test':
- packages/integration_test/**/*
platform-ios:
- packages/flutter_tools/lib/src/ios/**/*
-team:
- - '**/pubspec.yaml'
- - '**/fix_data.yaml'
- - '**/*.expect'
- - '**/*test_fixes*'
- - .github/**/*
- - dev/**/*
- - examples/**/*
- - packages/flutter_goldens/**/*
- - packages/flutter_goldens_client/**/*
-
-'gallery':
+'customer: gallery':
- examples/flutter_gallery/**/*
-tech-debt:
+'c: tech-debt':
- '**/fix_data.yaml'
- '**/*.expect'
- '**/*test_fixes*'
diff --git a/.github/move.yml b/.github/move.yml
deleted file mode 100644
index ba4009e..0000000
--- a/.github/move.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-# Configuration for move-issues - https://github.com/dessant/move-issues
-
-# Delete the command comment when it contains no other content.
-deleteCommand: true
-
-# Close the source issue after moving.
-closeSourceIssue: true
-
-# Lock the source issue after moving.
-lockSourceIssue: false
-
-# Mention issue and comment authors.
-mentionAuthors: true
-
-# Preserve mentions in the issue content.
-keepContentMentions: true
-
-# Set custom aliases for targets
-aliases:
- ide: flutter-intellij
diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml
index 6efaf8b..e24e455 100644
--- a/.github/workflows/labeler.yml
+++ b/.github/workflows/labeler.yml
@@ -17,6 +17,6 @@
runs-on: ubuntu-latest
steps:
# Source available at https://github.com/actions/labeler/blob/main/README.md
- - uses: actions/labeler@9fcb2c2f5584144ca754f8bfe8c6f81e77753375
+ - uses: actions/labeler@ac9175f8a1f3625fd0d4fb234536d26811351594
with:
sync-labels: false
diff --git a/.github/workflows/scorecards-analysis.yml b/.github/workflows/scorecards-analysis.yml
index e8a1868..31e4e43 100644
--- a/.github/workflows/scorecards-analysis.yml
+++ b/.github/workflows/scorecards-analysis.yml
@@ -28,7 +28,7 @@
persist-credentials: false
- name: "Run analysis"
- uses: ossf/scorecard-action@80e868c13c90f172d68d1f4501dee99e2479f7af
+ uses: ossf/scorecard-action@08b4669551908b1024bb425080c797723083c031
with:
results_file: results.sarif
results_format: sarif
diff --git a/.gitignore b/.gitignore
index a317f26..c21169b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,6 @@
+# Do not remove or rename entries in this file, only add new ones
+# See https://github.com/flutter/flutter/issues/128635 for more context.
+
# Miscellaneous
*.class
*.lock
@@ -53,6 +56,7 @@
**/generated_plugin_registrant.dart
.packages
.pub-preload-cache/
+.pub-cache/
.pub/
build/
flutter_*.png
diff --git a/TESTOWNERS b/TESTOWNERS
index e58be66..49f579e 100644
--- a/TESTOWNERS
+++ b/TESTOWNERS
@@ -61,7 +61,7 @@
/dev/devicelab/bin/tasks/gradient_dynamic_perf__e2e_summary.dart @flar @flutter/engine
/dev/devicelab/bin/tasks/gradient_static_perf__e2e_summary.dart @flar @flutter/engine
/dev/devicelab/bin/tasks/gradle_java8_compile_test.dart @reidbaker @flutter/tool
-/dev/devicelab/bin/tasks/hot_mode_dev_cycle_linux__benchmark.dart @zanderso @flutter/tool
+/dev/devicelab/bin/tasks/hot_mode_dev_cycle_linux__benchmark.dart @christopherfujino @flutter/tool
/dev/devicelab/bin/tasks/image_list_jit_reported_duration.dart @zanderso @flutter/engine
/dev/devicelab/bin/tasks/image_list_reported_duration.dart @zanderso @flutter/engine
/dev/devicelab/bin/tasks/large_image_changer_perf_android.dart @zanderso @flutter/engine
@@ -81,10 +81,12 @@
/dev/devicelab/bin/tasks/picture_cache_perf__e2e_summary.dart @zanderso @flutter/engine
/dev/devicelab/bin/tasks/platform_channels_benchmarks.dart @gaaclarke @flutter/engine
/dev/devicelab/bin/tasks/platform_views_scroll_perf__timeline_summary.dart @zanderso @flutter/engine
+/dev/devicelab/bin/tasks/platform_views_scroll_perf_impeller__timeline_summary.dart @bdero @flutter/engine
/dev/devicelab/bin/tasks/plugin_dependencies_test.dart @stuartmorgan @flutter/tool
/dev/devicelab/bin/tasks/raster_cache_use_memory_perf__e2e_summary.dart @flar @flutter/engine
/dev/devicelab/bin/tasks/routing_test.dart @zanderso @flutter/tool
/dev/devicelab/bin/tasks/shader_mask_cache_perf__e2e_summary.dart @flar @flutter/engine
+/dev/devicelab/bin/tasks/spell_check_test_ios.dart @camsim99 @flutter/android
/dev/devicelab/bin/tasks/spell_check_test.dart @camsim99 @flutter/android
/dev/devicelab/bin/tasks/textfield_perf__e2e_summary.dart @zanderso @flutter/engine
/dev/devicelab/bin/tasks/web_size__compile_test.dart @yjbanov @flutter/web
@@ -98,7 +100,7 @@
/dev/devicelab/bin/tasks/complex_layout_win__compile.dart @zanderso @flutter/tool
/dev/devicelab/bin/tasks/flavors_test_win.dart @zanderso @flutter/tool
/dev/devicelab/bin/tasks/flutter_gallery_win__compile.dart @zanderso @flutter/tool
-/dev/devicelab/bin/tasks/hot_mode_dev_cycle_win__benchmark.dart @zanderso @flutter/tool
+/dev/devicelab/bin/tasks/hot_mode_dev_cycle_win__benchmark.dart @andrewkolos @flutter/tool
/dev/devicelab/bin/tasks/windows_chrome_dev_mode.dart @yjbanov @flutter/web
## Mac Android DeviceLab tests
@@ -123,7 +125,7 @@
/dev/devicelab/bin/tasks/hello_world__memory.dart @zanderso @flutter/engine
/dev/devicelab/bin/tasks/hello_world_android__compile.dart @zanderso @flutter/tool
/dev/devicelab/bin/tasks/home_scroll_perf__timeline_summary.dart @zanderso @flutter/engine
-/dev/devicelab/bin/tasks/hot_mode_dev_cycle__benchmark.dart @zanderso @flutter/tool
+/dev/devicelab/bin/tasks/hot_mode_dev_cycle__benchmark.dart @eliasyishak @flutter/tool
/dev/devicelab/bin/tasks/hybrid_android_views_integration_test.dart @stuartmorgan @flutter/plugin
/dev/devicelab/bin/tasks/imagefiltered_transform_animation_perf__timeline_summary.dart @zanderso @flutter/engine
/dev/devicelab/bin/tasks/integration_test_test.dart @zanderso @flutter/tool
@@ -166,7 +168,7 @@
/dev/devicelab/bin/tasks/flutter_view_ios__start_up.dart @zanderso @flutter/engine
/dev/devicelab/bin/tasks/fullscreen_textfield_perf_ios__e2e_summary.dart @cyanglaz @flutter/engine
/dev/devicelab/bin/tasks/hello_world_ios__compile.dart @vashworth @flutter/engine
-/dev/devicelab/bin/tasks/hot_mode_dev_cycle_ios__benchmark.dart @zanderso @flutter/tool
+/dev/devicelab/bin/tasks/hot_mode_dev_cycle_ios__benchmark.dart @cyanglaz @flutter/tool
/dev/devicelab/bin/tasks/hot_mode_dev_cycle_ios_simulator.dart @cyanglaz @flutter/tool
/dev/devicelab/bin/tasks/hot_mode_dev_cycle_macos_target__benchmark.dart @cbracken @flutter/tool
/dev/devicelab/bin/tasks/imagefiltered_transform_animation_perf_ios__timeline_summary.dart @cyanglaz @flutter/engine
@@ -219,6 +221,7 @@
/dev/devicelab/bin/tasks/flutter_gallery_macos__start_up.dart @cbracken @flutter/desktop
/dev/devicelab/bin/tasks/flutter_gallery_win_desktop__compile.dart @yaakovschectman @flutter/desktop
/dev/devicelab/bin/tasks/flutter_gallery_win_desktop__start_up.dart @yaakovschectman @flutter/desktop
+/dev/devicelab/bin/tasks/flutter_tool_startup.dart @jensjoha @flutter/tool
/dev/devicelab/bin/tasks/flutter_tool_startup__linux.dart @jensjoha @flutter/tool
/dev/devicelab/bin/tasks/flutter_tool_startup__macos.dart @jensjoha @flutter/tool
/dev/devicelab/bin/tasks/flutter_tool_startup__windows.dart @jensjoha @flutter/tool
@@ -263,6 +266,7 @@
/dev/devicelab/bin/tasks/technical_debt__cost.dart @HansMuller @flutter/framework
/dev/devicelab/bin/tasks/web_benchmarks_canvaskit.dart @yjbanov @flutter/web
/dev/devicelab/bin/tasks/web_benchmarks_html.dart @yjbanov @flutter/web
+/dev/devicelab/bin/tasks/web_benchmarks_skwasm.dart @jacksongardner @flutter/web
/dev/devicelab/bin/tasks/windows_home_scroll_perf__timeline_summary.dart @jonahwilliams @flutter/engine
/dev/devicelab/bin/tasks/windows_startup_test.dart @loic-sharma @flutter/desktop
@@ -295,21 +299,21 @@
# TODO(keyonghan): add files/paths for below framework host only testss.
# https://github.com/flutter/flutter/issues/82068
#
-# build_tests @zanderso @flutter/tool
+# build_tests @eliasyishak @flutter/tool
# ci_yaml flutter roller @caseyhillers @flutter/infra
# coverage @godofredoc @flutter/infra
# flutter_packaging @godofredoc @flutter/infra
# flutter_plugins @stuartmorgan @flutter/plugin
# framework_tests @HansMuller @flutter/framework
-# fuchsia_precache @zanderso @flutter/tool
+# fuchsia_precache @christopherfujino @flutter/tool
# skp_generator @Hixie
# test_ownership @keyonghan
-# tool_host_cross_arch_tests @zanderso @flutter/tool
-# tool_integration_tests @zanderso @flutter/tool
-# tool_tests @zanderso @flutter/tool
-# verify_binaries_codesigned @christopherfujino @flutter/releases
+# tool_host_cross_arch_tests @andrewkolos @flutter/tool
+# tool_integration_tests @christopherfujino @flutter/tool
+# tool_tests @andrewkolos @flutter/tool
+# verify_binaries_codesigned @xilaizhang @flutter/releases
# web_canvaskit_tests @yjbanov @flutter/web
# web_integration_tests @yjbanov @flutter/web
# web_long_running_tests @yjbanov @flutter/web
# web_tests @yjbanov @flutter/web
-# web_tool_tests @zanderso @flutter/tool
+# web_tool_tests @eliasyishak @flutter/tool
diff --git a/analysis_options.yaml b/analysis_options.yaml
index b3f312d..747d8e2 100644
--- a/analysis_options.yaml
+++ b/analysis_options.yaml
@@ -1,16 +1,15 @@
# Specify analysis options.
#
-# For a list of lints, see: http://dart-lang.github.io/linter/lints/
-# See the configuration guide for more
-# https://github.com/dart-lang/sdk/tree/main/pkg/analyzer#configuring-the-analyzer
+# For a list of lints, see: https://dart.dev/lints
+# For guidelines on configuring static analysis, see:
+# https://dart.dev/guides/language/analysis-options
#
# There are other similar analysis options files in the flutter repos,
# which should be kept in sync with this file:
#
# - analysis_options.yaml (this file)
-# - https://github.com/flutter/plugins/blob/master/analysis_options.yaml
-# - https://github.com/flutter/engine/blob/master/analysis_options.yaml
-# - https://github.com/flutter/packages/blob/master/analysis_options.yaml
+# - https://github.com/flutter/engine/blob/main/analysis_options.yaml
+# - https://github.com/flutter/packages/blob/main/analysis_options.yaml
#
# This file contains the analysis options used for code in the flutter/flutter
# repository.
@@ -31,7 +30,7 @@
linter:
rules:
# This list is derived from the list of all available lints located at
- # https://github.com/dart-lang/linter/blob/master/example/all.yaml
+ # https://github.com/dart-lang/linter/blob/main/example/all.yaml
- always_declare_return_types
- always_put_control_body_on_new_line
# - always_put_required_named_parameters_first # we prefer having parameters in the same order as fields https://github.com/flutter/flutter/issues/10219
@@ -129,6 +128,7 @@
- no_logic_in_create_state
# - no_runtimeType_toString # ok in tests; we enable this only in packages/
- no_self_assignments
+ - no_wildcard_variable_uses
- non_constant_identifier_names
- noop_primitive_operations
- null_check_on_nullable_type_parameter
@@ -223,7 +223,7 @@
- unnecessary_string_interpolations
- unnecessary_this
- unnecessary_to_list_in_spreads
- # - unreachable_from_main # Do not enable this rule until it is un-marked as "experimental" and carefully re-evaluated.
+ - unreachable_from_main
- unrelated_type_equality_checks
- unsafe_html
- use_build_context_synchronously
diff --git a/bin/internal/engine.version b/bin/internal/engine.version
index 805ab72..05bb710 100644
--- a/bin/internal/engine.version
+++ b/bin/internal/engine.version
@@ -1 +1 @@
-2d8d5ecfe4a8326ad02e7c284e11d20fd09bccc6
+1b1ccdd1f527404a20656c8b1f8decd7061b0ba4
diff --git a/bin/internal/flutter_packages.version b/bin/internal/flutter_packages.version
index dcc605b..6dd2b6d 100644
--- a/bin/internal/flutter_packages.version
+++ b/bin/internal/flutter_packages.version
@@ -1 +1 @@
-050729760b251e315af01876cc7d7de5dcfba0e9
+250871431bedcfab9ca38b8a5170ab8761810f64
diff --git a/bin/internal/fuchsia-linux.version b/bin/internal/fuchsia-linux.version
index 67ec441..1fa79f2 100644
--- a/bin/internal/fuchsia-linux.version
+++ b/bin/internal/fuchsia-linux.version
@@ -1 +1 @@
-kQbij6Tvqe7F9-PhRtSXdbzZJ_bAgCWfjihkI73j0kYC
+1STsUj0X5YgpiSNEbqRCus0XRGJ-uLoTCxmjIVMy_EoC
diff --git a/bin/internal/fuchsia-mac.version b/bin/internal/fuchsia-mac.version
index dc9379a..3ee92df 100644
--- a/bin/internal/fuchsia-mac.version
+++ b/bin/internal/fuchsia-mac.version
@@ -1 +1 @@
-Cld7-rm6ZmCOO8j-Kgue15P2qmjgQGP9yC6yy7Fs-QYC
+0fvk838jTDNQ_l43kj5Vz-3ZA1JntonkaLZ8UJxQSaUC
diff --git a/bin/internal/shared.bat b/bin/internal/shared.bat
index d2f4160..421868a 100644
--- a/bin/internal/shared.bat
+++ b/bin/internal/shared.bat
@@ -128,6 +128,7 @@
:do_snapshot
IF EXIST "%FLUTTER_ROOT%\version" DEL "%FLUTTER_ROOT%\version"
+ IF EXIST "%FLUTTER_ROOT%\bin\cache\flutter.version.json" DEL "%FLUTTER_ROOT%\bin\cache\flutter.version.json"
ECHO: > "%cache_dir%\.dartignore"
ECHO Building flutter tool... 1>&2
PUSHD "%flutter_tools_dir%"
diff --git a/bin/internal/shared.sh b/bin/internal/shared.sh
index 93dc7d7..3532c23 100644
--- a/bin/internal/shared.sh
+++ b/bin/internal/shared.sh
@@ -123,7 +123,10 @@
# * STAMP_PATH is an empty file, or
# * Contents of STAMP_PATH is not what we are going to compile, or
# * pubspec.yaml last modified after pubspec.lock
- if [[ ! -f "$SNAPSHOT_PATH" || ! -s "$STAMP_PATH" || "$(cat "$STAMP_PATH")" != "$compilekey" || "$FLUTTER_TOOLS_DIR/pubspec.yaml" -nt "$FLUTTER_TOOLS_DIR/pubspec.lock" ]]; then
+ if [[ ! -f "$SNAPSHOT_PATH" || \
+ ! -s "$STAMP_PATH" || \
+ "$(cat "$STAMP_PATH")" != "$compilekey" || \
+ "$FLUTTER_TOOLS_DIR/pubspec.yaml" -nt "$FLUTTER_TOOLS_DIR/pubspec.lock" ]]; then
# Waits for the update lock to be acquired. Placing this check inside the
# conditional allows the majority of flutter/dart installations to bypass
# the lock entirely, but as a result this required a second verification that
@@ -137,6 +140,7 @@
# Fetch Dart...
rm -f "$FLUTTER_ROOT/version"
+ rm -f "$FLUTTER_ROOT/bin/cache/flutter.version.json"
touch "$FLUTTER_ROOT/bin/cache/.dartignore"
"$FLUTTER_ROOT/bin/internal/update_dart_sdk.sh"
diff --git a/dev/automated_tests/flutter_test/print_correct_local_widget_test.dart b/dev/automated_tests/flutter_test/print_correct_local_widget_test.dart
index c24a255..f00ceb5 100644
--- a/dev/automated_tests/flutter_test/print_correct_local_widget_test.dart
+++ b/dev/automated_tests/flutter_test/print_correct_local_widget_test.dart
@@ -10,6 +10,7 @@
// This should fail with user created widget = Row.
await tester.pumpWidget(
MaterialApp(
+ theme: ThemeData(useMaterial3: false),
home: Scaffold(
appBar: AppBar(
title: const Text('RenderFlex OverFlow'),
diff --git a/dev/automated_tests/pubspec.yaml b/dev/automated_tests/pubspec.yaml
index fb9ebc3..78466d3 100644
--- a/dev/automated_tests/pubspec.yaml
+++ b/dev/automated_tests/pubspec.yaml
@@ -13,10 +13,10 @@
integration_test:
sdk: flutter
platform: 3.1.0
- test: 1.24.3
+ test: 1.24.4
- _fe_analyzer_shared: 61.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- analyzer: 5.13.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ _fe_analyzer_shared: 62.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ analyzer: 6.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
args: 2.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
async: 2.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -26,6 +26,7 @@
convert: 3.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
coverage: 1.6.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
crypto: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ dart_internal: 0.2.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
fake_async: 1.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
file: 6.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
frontend_server_client: 3.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -52,16 +53,17 @@
source_map_stack_trace: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_maps: 0.10.12 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_core: 0.5.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_core: 0.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- vm_service: 11.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ vm_service: 11.7.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -71,4 +73,4 @@
assets:
- icon/test.png
-# PUBSPEC CHECKSUM: 0df7
+# PUBSPEC CHECKSUM: 62e1
diff --git a/dev/benchmarks/complex_layout/ios/Runner/Info.plist b/dev/benchmarks/complex_layout/ios/Runner/Info.plist
index acf7d7b..dd132e4 100644
--- a/dev/benchmarks/complex_layout/ios/Runner/Info.plist
+++ b/dev/benchmarks/complex_layout/ios/Runner/Info.plist
@@ -39,8 +39,6 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
- <key>UIViewControllerBasedStatusBarAppearance</key>
- <false/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
diff --git a/dev/benchmarks/complex_layout/pubspec.yaml b/dev/benchmarks/complex_layout/pubspec.yaml
index 063e6dd..4331605 100644
--- a/dev/benchmarks/complex_layout/pubspec.yaml
+++ b/dev/benchmarks/complex_layout/pubspec.yaml
@@ -21,42 +21,44 @@
characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
collection: 1.17.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
file: 6.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
matcher: 0.12.16 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.9.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path: 1.8.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
sync_http: 0.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- vm_service: 11.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ vm_service: 11.7.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
flutter_test:
sdk: flutter
- test: 1.24.3
+ test: 1.24.4
integration_test:
sdk: flutter
- _fe_analyzer_shared: 61.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- analyzer: 5.13.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ _fe_analyzer_shared: 62.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ analyzer: 6.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
args: 2.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
clock: 1.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
convert: 3.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
coverage: 1.6.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
crypto: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ dart_internal: 0.2.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
fake_async: 1.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
frontend_server_client: 3.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
glob: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http_multi_server: 3.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http_parser: 4.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
io: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
logging: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
mime: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
node_preamble: 2.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -69,7 +71,7 @@
shelf_web_socket: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_map_stack_trace: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_maps: 0.10.12 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_core: 0.5.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_core: 0.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -82,4 +84,4 @@
- packages/flutter_gallery_assets/people/square/ali.png
- packages/flutter_gallery_assets/places/india_chettinad_silk_maker.png
-# PUBSPEC CHECKSUM: 43d0
+# PUBSPEC CHECKSUM: e1ba
diff --git a/dev/benchmarks/complex_layout/windows/flutter/generated_plugins.cmake b/dev/benchmarks/complex_layout/windows/flutter/generated_plugins.cmake
deleted file mode 100644
index b93c4c3..0000000
--- a/dev/benchmarks/complex_layout/windows/flutter/generated_plugins.cmake
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Generated file, do not edit.
-#
-
-list(APPEND FLUTTER_PLUGIN_LIST
-)
-
-list(APPEND FLUTTER_FFI_PLUGIN_LIST
-)
-
-set(PLUGIN_BUNDLED_LIBRARIES)
-
-foreach(plugin ${FLUTTER_PLUGIN_LIST})
- add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin})
- target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
- list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
- list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
-endforeach(plugin)
-
-foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
- add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin})
- list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
-endforeach(ffi_plugin)
diff --git a/dev/benchmarks/macrobenchmarks/ios/Runner/Info.plist b/dev/benchmarks/macrobenchmarks/ios/Runner/Info.plist
index 6a54a91..3e5abf1 100644
--- a/dev/benchmarks/macrobenchmarks/ios/Runner/Info.plist
+++ b/dev/benchmarks/macrobenchmarks/ios/Runner/Info.plist
@@ -39,8 +39,6 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
- <key>UIViewControllerBasedStatusBarAppearance</key>
- <false/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
diff --git a/dev/benchmarks/macrobenchmarks/lib/src/web/bench_material_3.dart b/dev/benchmarks/macrobenchmarks/lib/src/web/bench_material_3.dart
index a531281..882ae92 100644
--- a/dev/benchmarks/macrobenchmarks/lib/src/web/bench_material_3.dart
+++ b/dev/benchmarks/macrobenchmarks/lib/src/web/bench_material_3.dart
@@ -3,8 +3,8 @@
// found in the LICENSE file.
import 'package:flutter/material.dart';
-import 'package:flutter/services.dart';
+import 'material3.dart';
import 'recorder.dart';
/// Measures how expensive it is to construct the material 3 components screen.
@@ -15,2330 +15,6 @@
@override
Widget createWidget() {
- return const Material3Components();
- }
-}
-
-const SizedBox rowDivider = SizedBox(width: 20);
-const SizedBox colDivider = SizedBox(height: 10);
-const double smallSpacing = 10.0;
-const double cardWidth = 115;
-const double widthConstraint = 450;
-
-class Material3Components extends StatefulWidget {
- const Material3Components({super.key});
-
- @override
- State<Material3Components> createState() => _Material3ComponentsState();
-}
-
-class _Material3ComponentsState extends State<Material3Components> {
- final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
-
- @override
- Widget build(BuildContext context) {
- return MaterialApp(
- home: Scaffold(
- key: scaffoldKey,
- body: Row(
- children: <Widget>[
- Expanded(
- child: FirstComponentList(
- showNavBottomBar: true,
- scaffoldKey: scaffoldKey,
- showSecondList: true,
- ),
- ),
- Expanded(
- child: SecondComponentList(scaffoldKey: scaffoldKey),
- ),
- ],
- ),
- ),
- );
- }
-}
-
-class FirstComponentList extends StatelessWidget {
- const FirstComponentList({
- super.key,
- required this.showNavBottomBar,
- required this.scaffoldKey,
- required this.showSecondList,
- });
-
- final bool showNavBottomBar;
- final GlobalKey<ScaffoldState> scaffoldKey;
- final bool showSecondList;
-
- @override
- Widget build(BuildContext context) {
- // Fully traverse this list before moving on.
- return FocusTraversalGroup(
- child: ListView(
- padding: showSecondList
- ? const EdgeInsetsDirectional.only(end: smallSpacing)
- : EdgeInsets.zero,
- children: <Widget>[
- const Actions(),
- colDivider,
- const Communication(),
- colDivider,
- const Containment(),
- if (!showSecondList) ...<Widget>[
- colDivider,
- Navigation(scaffoldKey: scaffoldKey),
- colDivider,
- const Selection(),
- colDivider,
- const TextInputs()
- ],
- ],
- ),
- );
- }
-}
-
-class SecondComponentList extends StatelessWidget {
- const SecondComponentList({
- super.key,
- required this.scaffoldKey,
- });
-
- final GlobalKey<ScaffoldState> scaffoldKey;
-
- @override
- Widget build(BuildContext context) {
- // Fully traverse this list before moving on.
- return FocusTraversalGroup(
- child: ListView(
- padding: const EdgeInsetsDirectional.only(end: smallSpacing),
- children: <Widget>[
- Navigation(scaffoldKey: scaffoldKey),
- colDivider,
- const Selection(),
- colDivider,
- const TextInputs(),
- ],
- ),
- );
- }
-}
-
-class Actions extends StatelessWidget {
- const Actions({super.key});
-
- @override
- Widget build(BuildContext context) {
- return const ComponentGroupDecoration(label: 'Actions', children: <Widget>[
- Buttons(),
- FloatingActionButtons(),
- IconToggleButtons(),
- SegmentedButtons(),
- ]);
- }
-}
-
-class Communication extends StatelessWidget {
- const Communication({super.key});
-
- @override
- Widget build(BuildContext context) {
- return const ComponentGroupDecoration(label: 'Communication', children: <Widget>[
- NavigationBars(
- selectedIndex: 1,
- isExampleBar: true,
- isBadgeExample: true,
- ),
- ProgressIndicators(),
- SnackBarSection(),
- ]);
- }
-}
-
-class Containment extends StatelessWidget {
- const Containment({super.key});
-
- @override
- Widget build(BuildContext context) {
- return const ComponentGroupDecoration(label: 'Containment', children: <Widget>[
- BottomSheetSection(),
- Cards(),
- Dialogs(),
- Dividers(),
- ]);
- }
-}
-
-class Navigation extends StatelessWidget {
- const Navigation({super.key, required this.scaffoldKey});
-
- final GlobalKey<ScaffoldState> scaffoldKey;
-
- @override
- Widget build(BuildContext context) {
- return ComponentGroupDecoration(label: 'Navigation', children: <Widget>[
- const BottomAppBars(),
- const NavigationBars(
- selectedIndex: 0,
- isExampleBar: true,
- ),
- NavigationDrawers(scaffoldKey: scaffoldKey),
- const NavigationRails(),
- const Tabs(),
- const TopAppBars(),
- ]);
- }
-}
-
-class Selection extends StatelessWidget {
- const Selection({super.key});
-
- @override
- Widget build(BuildContext context) {
- return const ComponentGroupDecoration(label: 'Selection', children: <Widget>[
- Checkboxes(),
- Chips(),
- Menus(),
- Radios(),
- Sliders(),
- Switches(),
- ]);
- }
-}
-
-class TextInputs extends StatelessWidget {
- const TextInputs({super.key});
-
- @override
- Widget build(BuildContext context) {
- return const ComponentGroupDecoration(
- label: 'Text inputs',
- children: <Widget>[TextFields()],
- );
- }
-}
-
-class Buttons extends StatefulWidget {
- const Buttons({super.key});
-
- @override
- State<Buttons> createState() => _ButtonsState();
-}
-
-class _ButtonsState extends State<Buttons> {
- @override
- Widget build(BuildContext context) {
- return const ComponentDecoration(
- label: 'Common buttons',
- tooltipMessage:
- 'Use ElevatedButton, FilledButton, FilledButton.tonal, OutlinedButton, or TextButton',
- child: SingleChildScrollView(
- scrollDirection: Axis.horizontal,
- child: Row(
- mainAxisAlignment: MainAxisAlignment.spaceAround,
- children: <Widget>[
- ButtonsWithoutIcon(isDisabled: false),
- ButtonsWithIcon(),
- ButtonsWithoutIcon(isDisabled: true),
- ],
- ),
- ),
- );
- }
-}
-
-class ButtonsWithoutIcon extends StatelessWidget {
- const ButtonsWithoutIcon({super.key, required this.isDisabled});
-
- final bool isDisabled;
-
- @override
- Widget build(BuildContext context) {
- return Padding(
- padding: const EdgeInsets.symmetric(horizontal: 5.0),
- child: IntrinsicWidth(
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.stretch,
- children: <Widget>[
- ElevatedButton(
- onPressed: isDisabled ? null : () {},
- child: const Text('Elevated'),
- ),
- colDivider,
- FilledButton(
- onPressed: isDisabled ? null : () {},
- child: const Text('Filled'),
- ),
- colDivider,
- FilledButton.tonal(
- onPressed: isDisabled ? null : () {},
- child: const Text('Filled tonal'),
- ),
- colDivider,
- OutlinedButton(
- onPressed: isDisabled ? null : () {},
- child: const Text('Outlined'),
- ),
- colDivider,
- TextButton(
- onPressed: isDisabled ? null : () {},
- child: const Text('Text'),
- ),
- ],
- ),
- ),
- );
- }
-}
-
-class ButtonsWithIcon extends StatelessWidget {
- const ButtonsWithIcon({super.key});
-
- @override
- Widget build(BuildContext context) {
- return Padding(
- padding: const EdgeInsets.symmetric(horizontal: 10.0),
- child: IntrinsicWidth(
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.stretch,
- children: <Widget>[
- ElevatedButton.icon(
- onPressed: () {},
- icon: const Icon(Icons.add),
- label: const Text('Icon'),
- ),
- colDivider,
- FilledButton.icon(
- onPressed: () {},
- label: const Text('Icon'),
- icon: const Icon(Icons.add),
- ),
- colDivider,
- FilledButton.tonalIcon(
- onPressed: () {},
- label: const Text('Icon'),
- icon: const Icon(Icons.add),
- ),
- colDivider,
- OutlinedButton.icon(
- onPressed: () {},
- icon: const Icon(Icons.add),
- label: const Text('Icon'),
- ),
- colDivider,
- TextButton.icon(
- onPressed: () {},
- icon: const Icon(Icons.add),
- label: const Text('Icon'),
- )
- ],
- ),
- ),
- );
- }
-}
-
-class FloatingActionButtons extends StatelessWidget {
- const FloatingActionButtons({super.key});
-
- @override
- Widget build(BuildContext context) {
- return ComponentDecoration(
- label: 'Floating action buttons',
- tooltipMessage:
- 'Use FloatingActionButton or FloatingActionButton.extended',
- child: Wrap(
- crossAxisAlignment: WrapCrossAlignment.center,
- runSpacing: smallSpacing,
- spacing: smallSpacing,
- children: <Widget>[
- FloatingActionButton.small(
- onPressed: () {},
- tooltip: 'Small',
- child: const Icon(Icons.add),
- ),
- FloatingActionButton.extended(
- onPressed: () {},
- tooltip: 'Extended',
- icon: const Icon(Icons.add),
- label: const Text('Create'),
- ),
- FloatingActionButton(
- onPressed: () {},
- tooltip: 'Standard',
- child: const Icon(Icons.add),
- ),
- FloatingActionButton.large(
- onPressed: () {},
- tooltip: 'Large',
- child: const Icon(Icons.add),
- ),
- ],
- ),
- );
- }
-}
-
-class Cards extends StatelessWidget {
- const Cards({super.key});
-
- @override
- Widget build(BuildContext context) {
- return ComponentDecoration(
- label: 'Cards',
- tooltipMessage: 'Use Card',
- child: Wrap(
- alignment: WrapAlignment.spaceEvenly,
- children: <Widget>[
- SizedBox(
- width: cardWidth,
- child: Card(
- child: Container(
- padding: const EdgeInsets.fromLTRB(10, 5, 5, 10),
- child: Column(
- children: <Widget>[
- Align(
- alignment: Alignment.topRight,
- child: IconButton(
- icon: const Icon(Icons.more_vert),
- onPressed: () {},
- ),
- ),
- const SizedBox(height: 20),
- const Align(
- alignment: Alignment.bottomLeft,
- child: Text('Elevated'),
- )
- ],
- ),
- ),
- ),
- ),
- SizedBox(
- width: cardWidth,
- child: Card(
- color: Theme.of(context).colorScheme.surfaceVariant,
- elevation: 0,
- child: Container(
- padding: const EdgeInsets.fromLTRB(10, 5, 5, 10),
- child: Column(
- children: <Widget>[
- Align(
- alignment: Alignment.topRight,
- child: IconButton(
- icon: const Icon(Icons.more_vert),
- onPressed: () {},
- ),
- ),
- const SizedBox(height: 20),
- const Align(
- alignment: Alignment.bottomLeft,
- child: Text('Filled'),
- )
- ],
- ),
- ),
- ),
- ),
- SizedBox(
- width: cardWidth,
- child: Card(
- elevation: 0,
- shape: RoundedRectangleBorder(
- side: BorderSide(
- color: Theme.of(context).colorScheme.outline,
- ),
- borderRadius: const BorderRadius.all(Radius.circular(12)),
- ),
- child: Container(
- padding: const EdgeInsets.fromLTRB(10, 5, 5, 10),
- child: Column(
- children: <Widget>[
- Align(
- alignment: Alignment.topRight,
- child: IconButton(
- icon: const Icon(Icons.more_vert),
- onPressed: () {},
- ),
- ),
- const SizedBox(height: 20),
- const Align(
- alignment: Alignment.bottomLeft,
- child: Text('Outlined'),
- )
- ],
- ),
- ),
- ),
- ),
- ],
- ),
- );
- }
-}
-
-class _ClearButton extends StatelessWidget {
- const _ClearButton({required this.controller});
-
- final TextEditingController controller;
-
- @override
- Widget build(BuildContext context) => IconButton(
- icon: const Icon(Icons.clear),
- onPressed: () => controller.clear(),
- );
-}
-
-class TextFields extends StatefulWidget {
- const TextFields({super.key});
-
- @override
- State<TextFields> createState() => _TextFieldsState();
-}
-
-class _TextFieldsState extends State<TextFields> {
- final TextEditingController _controllerFilled = TextEditingController();
- final TextEditingController _controllerOutlined = TextEditingController();
-
- @override
- Widget build(BuildContext context) {
- return ComponentDecoration(
- label: 'Text fields',
- tooltipMessage: 'Use TextField with different InputDecoration',
- child: Column(
- children: <Widget>[
- Padding(
- padding: const EdgeInsets.all(smallSpacing),
- child: TextField(
- controller: _controllerFilled,
- decoration: InputDecoration(
- prefixIcon: const Icon(Icons.search),
- suffixIcon: _ClearButton(controller: _controllerFilled),
- labelText: 'Filled',
- hintText: 'hint text',
- helperText: 'supporting text',
- filled: true,
- ),
- ),
- ),
- Padding(
- padding: const EdgeInsets.all(smallSpacing),
- child: Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: <Widget>[
- Flexible(
- child: SizedBox(
- width: 200,
- child: TextField(
- maxLength: 10,
- maxLengthEnforcement: MaxLengthEnforcement.none,
- controller: _controllerFilled,
- decoration: InputDecoration(
- prefixIcon: const Icon(Icons.search),
- suffixIcon: _ClearButton(controller: _controllerFilled),
- labelText: 'Filled',
- hintText: 'hint text',
- helperText: 'supporting text',
- filled: true,
- errorText: 'error text',
- ),
- ),
- ),
- ),
- const SizedBox(width: smallSpacing),
- Flexible(
- child: SizedBox(
- width: 200,
- child: TextField(
- controller: _controllerFilled,
- enabled: false,
- decoration: InputDecoration(
- prefixIcon: const Icon(Icons.search),
- suffixIcon: _ClearButton(controller: _controllerFilled),
- labelText: 'Disabled',
- hintText: 'hint text',
- helperText: 'supporting text',
- filled: true,
- ),
- ),
- ),
- ),
- ],
- ),
- ),
- Padding(
- padding: const EdgeInsets.all(smallSpacing),
- child: TextField(
- controller: _controllerOutlined,
- decoration: InputDecoration(
- prefixIcon: const Icon(Icons.search),
- suffixIcon: _ClearButton(controller: _controllerOutlined),
- labelText: 'Outlined',
- hintText: 'hint text',
- helperText: 'supporting text',
- border: const OutlineInputBorder(),
- ),
- ),
- ),
- Padding(
- padding: const EdgeInsets.all(smallSpacing),
- child: Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: <Widget>[
- Flexible(
- child: SizedBox(
- width: 200,
- child: TextField(
- controller: _controllerOutlined,
- decoration: InputDecoration(
- prefixIcon: const Icon(Icons.search),
- suffixIcon:
- _ClearButton(controller: _controllerOutlined),
- labelText: 'Outlined',
- hintText: 'hint text',
- helperText: 'supporting text',
- errorText: 'error text',
- border: const OutlineInputBorder(),
- filled: true,
- ),
- ),
- ),
- ),
- const SizedBox(width: smallSpacing),
- Flexible(
- child: SizedBox(
- width: 200,
- child: TextField(
- controller: _controllerOutlined,
- enabled: false,
- decoration: InputDecoration(
- prefixIcon: const Icon(Icons.search),
- suffixIcon:
- _ClearButton(controller: _controllerOutlined),
- labelText: 'Disabled',
- hintText: 'hint text',
- helperText: 'supporting text',
- border: const OutlineInputBorder(),
- filled: true,
- ),
- ),
- ),
- ),
- ])),
- ],
- ),
- );
- }
-}
-
-class Dialogs extends StatefulWidget {
- const Dialogs({super.key});
-
- @override
- State<Dialogs> createState() => _DialogsState();
-}
-
-class _DialogsState extends State<Dialogs> {
- void openDialog(BuildContext context) {
- showDialog<void>(
- context: context,
- builder: (BuildContext context) => AlertDialog(
- title: const Text('What is a dialog?'),
- content: const Text(
- 'A dialog is a type of modal window that appears in front of app content to provide critical information, or prompt for a decision to be made.'),
- actions: <Widget>[
- TextButton(
- child: const Text('Okay'),
- onPressed: () => Navigator.of(context).pop(),
- ),
- FilledButton(
- child: const Text('Dismiss'),
- onPressed: () => Navigator.of(context).pop(),
- ),
- ],
- ),
- );
- }
-
- void openFullscreenDialog(BuildContext context) {
- showDialog<void>(
- context: context,
- builder: (BuildContext context) => Dialog.fullscreen(
- child: Padding(
- padding: const EdgeInsets.all(20.0),
- child: Scaffold(
- appBar: AppBar(
- title: const Text('Full-screen dialog'),
- centerTitle: false,
- leading: IconButton(
- icon: const Icon(Icons.close),
- onPressed: () => Navigator.of(context).pop(),
- ),
- actions: <Widget>[
- TextButton(
- child: const Text('Close'),
- onPressed: () => Navigator.of(context).pop(),
- ),
- ],
- ),
- ),
- ),
- ),
- );
- }
-
- @override
- Widget build(BuildContext context) {
- return ComponentDecoration(
- label: 'Dialog',
- tooltipMessage:
- 'Use showDialog with Dialog.fullscreen, AlertDialog, or SimpleDialog',
- child: Wrap(
- alignment: WrapAlignment.spaceBetween,
- children: <Widget>[
- TextButton(
- child: const Text(
- 'Show dialog',
- style: TextStyle(fontWeight: FontWeight.bold),
- ),
- onPressed: () => openDialog(context),
- ),
- TextButton(
- child: const Text(
- 'Show full-screen dialog',
- style: TextStyle(fontWeight: FontWeight.bold),
- ),
- onPressed: () => openFullscreenDialog(context),
- ),
- ],
- ),
- );
- }
-}
-
-class Dividers extends StatelessWidget {
- const Dividers({super.key});
-
- @override
- Widget build(BuildContext context) {
- return const ComponentDecoration(
- label: 'Dividers',
- tooltipMessage: 'Use Divider or VerticalDivider',
- child: Column(
- children: <Widget>[
- Divider(key: Key('divider')),
- ],
- ),
- );
- }
-}
-
-class Switches extends StatelessWidget {
- const Switches({super.key});
-
- @override
- Widget build(BuildContext context) {
- return const ComponentDecoration(
- label: 'Switches',
- tooltipMessage: 'Use SwitchListTile or Switch',
- child: Column(
- children: <Widget>[
- SwitchRow(isEnabled: true),
- SwitchRow(isEnabled: false),
- ],
- ),
- );
- }
-}
-
-class SwitchRow extends StatefulWidget {
- const SwitchRow({super.key, required this.isEnabled});
-
- final bool isEnabled;
-
- @override
- State<SwitchRow> createState() => _SwitchRowState();
-}
-
-class _SwitchRowState extends State<SwitchRow> {
- bool value0 = false;
- bool value1 = true;
-
- final MaterialStateProperty<Icon?> thumbIcon =
- MaterialStateProperty.resolveWith<Icon?>((Set<MaterialState> states) {
- if (states.contains(MaterialState.selected)) {
- return const Icon(Icons.check);
- }
- return const Icon(Icons.close);
- });
-
- @override
- Widget build(BuildContext context) {
- return Row(
- mainAxisAlignment: MainAxisAlignment.spaceEvenly,
- children: <Widget>[
- Switch(
- value: value0,
- onChanged: widget.isEnabled
- ? (bool value) {
- setState(() {
- value0 = value;
- });
- }
- : null,
- ),
- Switch(
- thumbIcon: thumbIcon,
- value: value1,
- onChanged: widget.isEnabled
- ? (bool value) {
- setState(() {
- value1 = value;
- });
- }
- : null,
- ),
- ],
- );
- }
-}
-
-class Checkboxes extends StatefulWidget {
- const Checkboxes({super.key});
-
- @override
- State<Checkboxes> createState() => _CheckboxesState();
-}
-
-class _CheckboxesState extends State<Checkboxes> {
- bool? isChecked0 = true;
- bool? isChecked1;
- bool? isChecked2 = false;
-
- @override
- Widget build(BuildContext context) {
- return ComponentDecoration(
- label: 'Checkboxes',
- tooltipMessage: 'Use CheckboxListTile or Checkbox',
- child: Column(
- children: <Widget>[
- CheckboxListTile(
- tristate: true,
- value: isChecked0,
- title: const Text('Option 1'),
- onChanged: (bool? value) {
- setState(() {
- isChecked0 = value;
- });
- },
- ),
- CheckboxListTile(
- tristate: true,
- value: isChecked1,
- title: const Text('Option 2'),
- onChanged: (bool? value) {
- setState(() {
- isChecked1 = value;
- });
- },
- ),
- CheckboxListTile(
- tristate: true,
- value: isChecked2,
- title: const Text('Option 3'),
- onChanged: (bool? value) {
- setState(() {
- isChecked2 = value;
- });
- },
- ),
- const CheckboxListTile(
- tristate: true,
- title: Text('Option 4'),
- value: true,
- onChanged: null,
- ),
- ],
- ),
- );
- }
-}
-
-enum Value { first, second }
-
-class Radios extends StatefulWidget {
- const Radios({super.key});
-
- @override
- State<Radios> createState() => _RadiosState();
-}
-
-enum Options { option1, option2, option3 }
-
-class _RadiosState extends State<Radios> {
- Options? _selectedOption = Options.option1;
-
- @override
- Widget build(BuildContext context) {
- return ComponentDecoration(
- label: 'Radio buttons',
- tooltipMessage: 'Use RadioListTile<T> or Radio<T>',
- child: Column(
- children: <Widget>[
- RadioListTile<Options>(
- title: const Text('Option 1'),
- value: Options.option1,
- groupValue: _selectedOption,
- onChanged: (Options? value) {
- setState(() {
- _selectedOption = value;
- });
- },
- ),
- RadioListTile<Options>(
- title: const Text('Option 2'),
- value: Options.option2,
- groupValue: _selectedOption,
- onChanged: (Options? value) {
- setState(() {
- _selectedOption = value;
- });
- },
- ),
- RadioListTile<Options>(
- title: const Text('Option 3'),
- value: Options.option3,
- groupValue: _selectedOption,
- onChanged: null,
- ),
- ],
- ),
- );
- }
-}
-
-class ProgressIndicators extends StatefulWidget {
- const ProgressIndicators({super.key});
-
- @override
- State<ProgressIndicators> createState() => _ProgressIndicatorsState();
-}
-
-class _ProgressIndicatorsState extends State<ProgressIndicators> {
- bool playProgressIndicator = false;
-
- @override
- Widget build(BuildContext context) {
- final double? progressValue = playProgressIndicator ? null : 0.7;
-
- return ComponentDecoration(
- label: 'Progress indicators',
- tooltipMessage:
- 'Use CircularProgressIndicator or LinearProgressIndicator',
- child: Column(
- children: <Widget>[
- Row(
- children: <Widget>[
- IconButton(
- isSelected: playProgressIndicator,
- selectedIcon: const Icon(Icons.pause),
- icon: const Icon(Icons.play_arrow),
- onPressed: () {
- setState(() {
- playProgressIndicator = !playProgressIndicator;
- });
- },
- ),
- Expanded(
- child: Row(
- children: <Widget>[
- rowDivider,
- CircularProgressIndicator(
- value: progressValue,
- ),
- rowDivider,
- Expanded(
- child: LinearProgressIndicator(
- value: progressValue,
- ),
- ),
- rowDivider,
- ],
- ),
- ),
- ],
- ),
- ],
- ),
- );
- }
-}
-
-const List<NavigationDestination> appBarDestinations = <NavigationDestination>[
- NavigationDestination(
- tooltip: '',
- icon: Icon(Icons.widgets_outlined),
- label: 'Components',
- selectedIcon: Icon(Icons.widgets),
- ),
- NavigationDestination(
- tooltip: '',
- icon: Icon(Icons.format_paint_outlined),
- label: 'Color',
- selectedIcon: Icon(Icons.format_paint),
- ),
- NavigationDestination(
- tooltip: '',
- icon: Icon(Icons.text_snippet_outlined),
- label: 'Typography',
- selectedIcon: Icon(Icons.text_snippet),
- ),
- NavigationDestination(
- tooltip: '',
- icon: Icon(Icons.invert_colors_on_outlined),
- label: 'Elevation',
- selectedIcon: Icon(Icons.opacity),
- )
-];
-
-const List<Widget> exampleBarDestinations = <Widget>[
- NavigationDestination(
- tooltip: '',
- icon: Icon(Icons.explore_outlined),
- label: 'Explore',
- selectedIcon: Icon(Icons.explore),
- ),
- NavigationDestination(
- tooltip: '',
- icon: Icon(Icons.pets_outlined),
- label: 'Pets',
- selectedIcon: Icon(Icons.pets),
- ),
- NavigationDestination(
- tooltip: '',
- icon: Icon(Icons.account_box_outlined),
- label: 'Account',
- selectedIcon: Icon(Icons.account_box),
- )
-];
-
-List<Widget> barWithBadgeDestinations = <Widget>[
- NavigationDestination(
- tooltip: '',
- icon: Badge.count(count: 1000, child: const Icon(Icons.mail_outlined)),
- label: 'Mail',
- selectedIcon: Badge.count(count: 1000, child: const Icon(Icons.mail)),
- ),
- const NavigationDestination(
- tooltip: '',
- icon: Badge(label: Text('10'), child: Icon(Icons.chat_bubble_outline)),
- label: 'Chat',
- selectedIcon: Badge(label: Text('10'), child: Icon(Icons.chat_bubble)),
- ),
- const NavigationDestination(
- tooltip: '',
- icon: Badge(child: Icon(Icons.group_outlined)),
- label: 'Rooms',
- selectedIcon: Badge(child: Icon(Icons.group_rounded)),
- ),
- NavigationDestination(
- tooltip: '',
- icon: Badge.count(count: 3, child: const Icon(Icons.videocam_outlined)),
- label: 'Meet',
- selectedIcon: Badge.count(count: 3, child: const Icon(Icons.videocam)),
- )
-];
-
-class NavigationBars extends StatefulWidget {
- const NavigationBars({
- super.key,
- this.onSelectItem,
- required this.selectedIndex,
- required this.isExampleBar,
- this.isBadgeExample = false,
- });
-
- final void Function(int)? onSelectItem;
- final int selectedIndex;
- final bool isExampleBar;
- final bool isBadgeExample;
-
- @override
- State<NavigationBars> createState() => _NavigationBarsState();
-}
-
-class _NavigationBarsState extends State<NavigationBars> {
- late int selectedIndex;
-
- @override
- void initState() {
- super.initState();
- selectedIndex = widget.selectedIndex;
- }
-
- @override
- void didUpdateWidget(covariant NavigationBars oldWidget) {
- super.didUpdateWidget(oldWidget);
- if (widget.selectedIndex != oldWidget.selectedIndex) {
- selectedIndex = widget.selectedIndex;
- }
- }
-
- @override
- Widget build(BuildContext context) {
- // App NavigationBar should get first focus.
- Widget navigationBar = Focus(
- autofocus: !(widget.isExampleBar || widget.isBadgeExample),
- child: NavigationBar(
- selectedIndex: selectedIndex,
- onDestinationSelected: (int index) {
- setState(() {
- selectedIndex = index;
- });
- if (!widget.isExampleBar) {
- widget.onSelectItem!(index);
- }
- },
- destinations: widget.isExampleBar && widget.isBadgeExample
- ? barWithBadgeDestinations
- : widget.isExampleBar
- ? exampleBarDestinations
- : appBarDestinations,
- ),
- );
-
- if (widget.isExampleBar && widget.isBadgeExample) {
- navigationBar = ComponentDecoration(
- label: 'Badges',
- tooltipMessage: 'Use Badge or Badge.count',
- child: navigationBar);
- } else if (widget.isExampleBar) {
- navigationBar = ComponentDecoration(
- label: 'Navigation bar',
- tooltipMessage: 'Use NavigationBar',
- child: navigationBar);
- }
-
- return navigationBar;
- }
-}
-
-class IconToggleButtons extends StatefulWidget {
- const IconToggleButtons({super.key});
-
- @override
- State<IconToggleButtons> createState() => _IconToggleButtonsState();
-}
-
-class _IconToggleButtonsState extends State<IconToggleButtons> {
- @override
- Widget build(BuildContext context) {
- return const ComponentDecoration(
- label: 'Icon buttons',
- tooltipMessage: 'Use IconButton',
- child: Row(
- mainAxisAlignment: MainAxisAlignment.spaceAround,
- children: <Widget>[
- Column(
- // Standard IconButton
- children: <Widget>[
- IconToggleButton(
- isEnabled: true,
- tooltip: 'Standard',
- ),
- colDivider,
- IconToggleButton(
- isEnabled: false,
- tooltip: 'Standard (disabled)',
- ),
- ],
- ),
- Column(
- children: <Widget>[
- // Filled IconButton
- IconToggleButton(
- isEnabled: true,
- tooltip: 'Filled',
- getDefaultStyle: enabledFilledButtonStyle,
- ),
- colDivider,
- IconToggleButton(
- isEnabled: false,
- tooltip: 'Filled (disabled)',
- getDefaultStyle: disabledFilledButtonStyle,
- ),
- ],
- ),
- Column(
- children: <Widget>[
- // Filled Tonal IconButton
- IconToggleButton(
- isEnabled: true,
- tooltip: 'Filled tonal',
- getDefaultStyle: enabledFilledTonalButtonStyle,
- ),
- colDivider,
- IconToggleButton(
- isEnabled: false,
- tooltip: 'Filled tonal (disabled)',
- getDefaultStyle: disabledFilledTonalButtonStyle,
- ),
- ],
- ),
- Column(
- children: <Widget>[
- // Outlined IconButton
- IconToggleButton(
- isEnabled: true,
- tooltip: 'Outlined',
- getDefaultStyle: enabledOutlinedButtonStyle,
- ),
- colDivider,
- IconToggleButton(
- isEnabled: false,
- tooltip: 'Outlined (disabled)',
- getDefaultStyle: disabledOutlinedButtonStyle,
- ),
- ],
- ),
- ],
- ),
- );
- }
-}
-
-class IconToggleButton extends StatefulWidget {
- const IconToggleButton({
- required this.isEnabled,
- required this.tooltip,
- this.getDefaultStyle,
- super.key,
- });
-
- final bool isEnabled;
- final String tooltip;
- final ButtonStyle? Function(bool, ColorScheme)? getDefaultStyle;
-
- @override
- State<IconToggleButton> createState() => _IconToggleButtonState();
-}
-
-class _IconToggleButtonState extends State<IconToggleButton> {
- bool selected = false;
-
- @override
- Widget build(BuildContext context) {
- final ColorScheme colors = Theme.of(context).colorScheme;
- final VoidCallback? onPressed = widget.isEnabled
- ? () {
- setState(() {
- selected = !selected;
- });
- }
- : null;
- final ButtonStyle? style = widget.getDefaultStyle?.call(selected, colors);
-
- return IconButton(
- visualDensity: VisualDensity.standard,
- isSelected: selected,
- tooltip: widget.tooltip,
- icon: const Icon(Icons.settings_outlined),
- selectedIcon: const Icon(Icons.settings),
- onPressed: onPressed,
- style: style,
- );
- }
-}
-
-ButtonStyle enabledFilledButtonStyle(bool selected, ColorScheme colors) {
- return IconButton.styleFrom(
- foregroundColor: selected ? colors.onPrimary : colors.primary,
- backgroundColor: selected ? colors.primary : colors.surfaceVariant,
- disabledForegroundColor: colors.onSurface.withOpacity(0.38),
- disabledBackgroundColor: colors.onSurface.withOpacity(0.12),
- hoverColor: selected
- ? colors.onPrimary.withOpacity(0.08)
- : colors.primary.withOpacity(0.08),
- focusColor: selected
- ? colors.onPrimary.withOpacity(0.12)
- : colors.primary.withOpacity(0.12),
- highlightColor: selected
- ? colors.onPrimary.withOpacity(0.12)
- : colors.primary.withOpacity(0.12),
- );
-}
-
-ButtonStyle disabledFilledButtonStyle(bool selected, ColorScheme colors) {
- return IconButton.styleFrom(
- disabledForegroundColor: colors.onSurface.withOpacity(0.38),
- disabledBackgroundColor: colors.onSurface.withOpacity(0.12),
- );
-}
-
-ButtonStyle enabledFilledTonalButtonStyle(bool selected, ColorScheme colors) {
- return IconButton.styleFrom(
- foregroundColor:
- selected ? colors.onSecondaryContainer : colors.onSurfaceVariant,
- backgroundColor:
- selected ? colors.secondaryContainer : colors.surfaceVariant,
- hoverColor: selected
- ? colors.onSecondaryContainer.withOpacity(0.08)
- : colors.onSurfaceVariant.withOpacity(0.08),
- focusColor: selected
- ? colors.onSecondaryContainer.withOpacity(0.12)
- : colors.onSurfaceVariant.withOpacity(0.12),
- highlightColor: selected
- ? colors.onSecondaryContainer.withOpacity(0.12)
- : colors.onSurfaceVariant.withOpacity(0.12),
- );
-}
-
-ButtonStyle disabledFilledTonalButtonStyle(bool selected, ColorScheme colors) {
- return IconButton.styleFrom(
- disabledForegroundColor: colors.onSurface.withOpacity(0.38),
- disabledBackgroundColor: colors.onSurface.withOpacity(0.12),
- );
-}
-
-ButtonStyle enabledOutlinedButtonStyle(bool selected, ColorScheme colors) {
- return IconButton.styleFrom(
- backgroundColor: selected ? colors.inverseSurface : null,
- hoverColor: selected
- ? colors.onInverseSurface.withOpacity(0.08)
- : colors.onSurfaceVariant.withOpacity(0.08),
- focusColor: selected
- ? colors.onInverseSurface.withOpacity(0.12)
- : colors.onSurfaceVariant.withOpacity(0.12),
- highlightColor: selected
- ? colors.onInverseSurface.withOpacity(0.12)
- : colors.onSurface.withOpacity(0.12),
- side: BorderSide(color: colors.outline),
- ).copyWith(
- foregroundColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
- if (states.contains(MaterialState.selected)) {
- return colors.onInverseSurface;
- }
- if (states.contains(MaterialState.pressed)) {
- return colors.onSurface;
- }
- return null;
- }),
- );
-}
-
-ButtonStyle disabledOutlinedButtonStyle(bool selected, ColorScheme colors) {
- return IconButton.styleFrom(
- disabledForegroundColor: colors.onSurface.withOpacity(0.38),
- disabledBackgroundColor:
- selected ? colors.onSurface.withOpacity(0.12) : null,
- side: selected ? null : BorderSide(color: colors.outline.withOpacity(0.12)),
- );
-}
-
-class Chips extends StatefulWidget {
- const Chips({super.key});
-
- @override
- State<Chips> createState() => _ChipsState();
-}
-
-class _ChipsState extends State<Chips> {
- bool isFiltered = true;
-
- @override
- Widget build(BuildContext context) {
- return ComponentDecoration(
- label: 'Chips',
- tooltipMessage:
- 'Use ActionChip, FilterChip, or InputChip. \nActionChip can also be used for suggestion chip',
- child: Column(
- children: <Widget>[
- Wrap(
- spacing: smallSpacing,
- runSpacing: smallSpacing,
- children: <Widget>[
- ActionChip(
- label: const Text('Assist'),
- avatar: const Icon(Icons.event),
- onPressed: () {},
- ),
- FilterChip(
- label: const Text('Filter'),
- selected: isFiltered,
- onSelected: (bool selected) {
- setState(() => isFiltered = selected);
- },
- ),
- InputChip(
- label: const Text('Input'),
- onPressed: () {},
- onDeleted: () {},
- ),
- ActionChip(
- label: const Text('Suggestion'),
- onPressed: () {},
- ),
- ],
- ),
- colDivider,
- Wrap(
- spacing: smallSpacing,
- runSpacing: smallSpacing,
- children: <Widget>[
- const ActionChip(
- label: Text('Assist'),
- avatar: Icon(Icons.event),
- ),
- FilterChip(
- label: const Text('Filter'),
- selected: isFiltered,
- onSelected: null,
- ),
- InputChip(
- label: const Text('Input'),
- onDeleted: () {},
- isEnabled: false,
- ),
- const ActionChip(
- label: Text('Suggestion'),
- ),
- ],
- ),
- ],
- ),
- );
- }
-}
-
-class SegmentedButtons extends StatelessWidget {
- const SegmentedButtons({super.key});
-
- @override
- Widget build(BuildContext context) {
- return const ComponentDecoration(
- label: 'Segmented buttons',
- tooltipMessage: 'Use SegmentedButton<T>',
- child: Column(
- children: <Widget>[
- SingleChoice(),
- colDivider,
- MultipleChoice(),
- ],
- ),
- );
- }
-}
-
-enum Calendar { day, week, month, year }
-
-class SingleChoice extends StatefulWidget {
- const SingleChoice({super.key});
-
- @override
- State<SingleChoice> createState() => _SingleChoiceState();
-}
-
-class _SingleChoiceState extends State<SingleChoice> {
- Calendar calendarView = Calendar.day;
-
- @override
- Widget build(BuildContext context) {
- return SegmentedButton<Calendar>(
- segments: const <ButtonSegment<Calendar>>[
- ButtonSegment<Calendar>(
- value: Calendar.day,
- label: Text('Day'),
- icon: Icon(Icons.calendar_view_day)),
- ButtonSegment<Calendar>(
- value: Calendar.week,
- label: Text('Week'),
- icon: Icon(Icons.calendar_view_week)),
- ButtonSegment<Calendar>(
- value: Calendar.month,
- label: Text('Month'),
- icon: Icon(Icons.calendar_view_month)),
- ButtonSegment<Calendar>(
- value: Calendar.year,
- label: Text('Year'),
- icon: Icon(Icons.calendar_today)),
- ],
- selected: <Calendar>{calendarView},
- onSelectionChanged: (Set<Calendar> newSelection) {
- setState(() {
- // By default there is only a single segment that can be
- // selected at one time, so its value is always the first
- // item in the selected set.
- calendarView = newSelection.first;
- });
- },
- );
- }
-}
-
-enum Sizes { extraSmall, small, medium, large, extraLarge }
-
-class MultipleChoice extends StatefulWidget {
- const MultipleChoice({super.key});
-
- @override
- State<MultipleChoice> createState() => _MultipleChoiceState();
-}
-
-class _MultipleChoiceState extends State<MultipleChoice> {
- Set<Sizes> selection = <Sizes>{Sizes.large, Sizes.extraLarge};
-
- @override
- Widget build(BuildContext context) {
- return SegmentedButton<Sizes>(
- segments: const <ButtonSegment<Sizes>>[
- ButtonSegment<Sizes>(value: Sizes.extraSmall, label: Text('XS')),
- ButtonSegment<Sizes>(value: Sizes.small, label: Text('S')),
- ButtonSegment<Sizes>(value: Sizes.medium, label: Text('M')),
- ButtonSegment<Sizes>(
- value: Sizes.large,
- label: Text('L'),
- ),
- ButtonSegment<Sizes>(value: Sizes.extraLarge, label: Text('XL')),
- ],
- selected: selection,
- onSelectionChanged: (Set<Sizes> newSelection) {
- setState(() {
- selection = newSelection;
- });
- },
- multiSelectionEnabled: true,
- );
- }
-}
-
-class SnackBarSection extends StatelessWidget {
- const SnackBarSection({super.key});
-
- @override
- Widget build(BuildContext context) {
- return ComponentDecoration(
- label: 'Snackbar',
- tooltipMessage:
- 'Use ScaffoldMessenger.of(context).showSnackBar with SnackBar',
- child: TextButton(
- onPressed: () {
- final SnackBar snackBar = SnackBar(
- behavior: SnackBarBehavior.floating,
- width: 400.0,
- content: const Text('This is a snackbar'),
- action: SnackBarAction(
- label: 'Close',
- onPressed: () {},
- ),
- );
-
- ScaffoldMessenger.of(context).hideCurrentSnackBar();
- ScaffoldMessenger.of(context).showSnackBar(snackBar);
- },
- child: const Text(
- 'Show snackbar',
- style: TextStyle(fontWeight: FontWeight.bold),
- ),
- ),
- );
- }
-}
-
-class BottomSheetSection extends StatefulWidget {
- const BottomSheetSection({super.key});
-
- @override
- State<BottomSheetSection> createState() => _BottomSheetSectionState();
-}
-
-class _BottomSheetSectionState extends State<BottomSheetSection> {
- bool isNonModalBottomSheetOpen = false;
- PersistentBottomSheetController<void>? _nonModalBottomSheetController;
-
- @override
- Widget build(BuildContext context) {
- List<Widget> buttonList = <Widget>[
- IconButton(onPressed: () {}, icon: const Icon(Icons.share_outlined)),
- IconButton(onPressed: () {}, icon: const Icon(Icons.add)),
- IconButton(onPressed: () {}, icon: const Icon(Icons.delete_outline)),
- IconButton(onPressed: () {}, icon: const Icon(Icons.archive_outlined)),
- IconButton(onPressed: () {}, icon: const Icon(Icons.settings_outlined)),
- IconButton(onPressed: () {}, icon: const Icon(Icons.favorite_border)),
- ];
- const List<Text> labelList = <Text>[
- Text('Share'),
- Text('Add to'),
- Text('Trash'),
- Text('Archive'),
- Text('Settings'),
- Text('Favorite')
- ];
-
- buttonList = List<Widget>.generate(
- buttonList.length,
- (int index) => Padding(
- padding: const EdgeInsets.fromLTRB(20.0, 30.0, 20.0, 20.0),
- child: Column(
- children: <Widget>[
- buttonList[index],
- labelList[index],
- ],
- ),
- ));
-
- return ComponentDecoration(
- label: 'Bottom sheet',
- tooltipMessage: 'Use showModalBottomSheet<T> or showBottomSheet<T>',
- child: Wrap(
- alignment: WrapAlignment.spaceEvenly,
- children: <Widget>[
- TextButton(
- child: const Text(
- 'Show modal bottom sheet',
- style: TextStyle(fontWeight: FontWeight.bold),
- ),
- onPressed: () {
- showModalBottomSheet<void>(
- context: context,
- constraints: const BoxConstraints(maxWidth: 640),
- builder: (BuildContext context) {
- return SizedBox(
- height: 150,
- child: Padding(
- padding: const EdgeInsets.symmetric(horizontal: 32.0),
- child: ListView(
- shrinkWrap: true,
- scrollDirection: Axis.horizontal,
- children: buttonList,
- ),
- ),
- );
- },
- );
- },
- ),
- TextButton(
- child: Text(
- isNonModalBottomSheetOpen
- ? 'Hide bottom sheet'
- : 'Show bottom sheet',
- style: const TextStyle(fontWeight: FontWeight.bold),
- ),
- onPressed: () {
- if (isNonModalBottomSheetOpen) {
- _nonModalBottomSheetController?.close();
- setState(() {
- isNonModalBottomSheetOpen = false;
- });
- return;
- } else {
- setState(() {
- isNonModalBottomSheetOpen = true;
- });
- }
-
- _nonModalBottomSheetController = showBottomSheet<void>(
- elevation: 8.0,
- context: context,
- constraints: const BoxConstraints(maxWidth: 640),
- builder: (BuildContext context) {
- return SizedBox(
- height: 150,
- child: Padding(
- padding: const EdgeInsets.symmetric(horizontal: 32.0),
- child: ListView(
- shrinkWrap: true,
- scrollDirection: Axis.horizontal,
- children: buttonList,
- ),
- ),
- );
- },
- );
- },
- ),
- ],
- ),
- );
- }
-}
-
-class BottomAppBars extends StatelessWidget {
- const BottomAppBars({super.key});
-
- @override
- Widget build(BuildContext context) {
- return ComponentDecoration(
- label: 'Bottom app bar',
- tooltipMessage: 'Use BottomAppBar',
- child: Column(
- children: <Widget>[
- SizedBox(
- height: 80,
- child: Scaffold(
- floatingActionButton: FloatingActionButton(
- onPressed: () {},
- elevation: 0.0,
- child: const Icon(Icons.add),
- ),
- floatingActionButtonLocation:
- FloatingActionButtonLocation.endContained,
- bottomNavigationBar: BottomAppBar(
- child: Row(
- children: <Widget>[
- const IconButtonAnchorExample(),
- IconButton(
- tooltip: 'Search',
- icon: const Icon(Icons.search),
- onPressed: () {},
- ),
- IconButton(
- tooltip: 'Favorite',
- icon: const Icon(Icons.favorite),
- onPressed: () {},
- ),
- ],
- ),
- ),
- ),
- ),
- ],
- ),
- );
- }
-}
-
-class IconButtonAnchorExample extends StatelessWidget {
- const IconButtonAnchorExample({super.key});
-
- @override
- Widget build(BuildContext context) {
- return MenuAnchor(
- builder: (BuildContext context, MenuController controller, Widget? child) {
- return IconButton(
- onPressed: () {
- if (controller.isOpen) {
- controller.close();
- } else {
- controller.open();
- }
- },
- icon: const Icon(Icons.more_vert),
- );
- },
- menuChildren: <Widget>[
- MenuItemButton(
- child: const Text('Menu 1'),
- onPressed: () {},
- ),
- MenuItemButton(
- child: const Text('Menu 2'),
- onPressed: () {},
- ),
- SubmenuButton(
- menuChildren: <Widget>[
- MenuItemButton(
- onPressed: () {},
- child: const Text('Menu 3.1'),
- ),
- MenuItemButton(
- onPressed: () {},
- child: const Text('Menu 3.2'),
- ),
- MenuItemButton(
- onPressed: () {},
- child: const Text('Menu 3.3'),
- ),
- ],
- child: const Text('Menu 3'),
- ),
- ],
- );
- }
-}
-
-class ButtonAnchorExample extends StatelessWidget {
- const ButtonAnchorExample({super.key});
-
- @override
- Widget build(BuildContext context) {
- return MenuAnchor(
- builder: (BuildContext context, MenuController controller, Widget? child) {
- return FilledButton.tonal(
- onPressed: () {
- if (controller.isOpen) {
- controller.close();
- } else {
- controller.open();
- }
- },
- child: const Text('Show menu'),
- );
- },
- menuChildren: <Widget>[
- MenuItemButton(
- leadingIcon: const Icon(Icons.people_alt_outlined),
- child: const Text('Item 1'),
- onPressed: () {},
- ),
- MenuItemButton(
- leadingIcon: const Icon(Icons.remove_red_eye_outlined),
- child: const Text('Item 2'),
- onPressed: () {},
- ),
- MenuItemButton(
- leadingIcon: const Icon(Icons.refresh),
- onPressed: () {},
- child: const Text('Item 3'),
- ),
- ],
- );
- }
-}
-
-class NavigationDrawers extends StatelessWidget {
- const NavigationDrawers({super.key, required this.scaffoldKey});
- final GlobalKey<ScaffoldState> scaffoldKey;
-
- @override
- Widget build(BuildContext context) {
- return ComponentDecoration(
- label: 'Navigation drawer',
- tooltipMessage:
- 'Use NavigationDrawer. For modal navigation drawers, see Scaffold.endDrawer',
- child: Column(
- children: <Widget>[
- const SizedBox(height: 520, child: NavigationDrawerSection()),
- colDivider,
- colDivider,
- TextButton(
- child: const Text('Show modal navigation drawer',
- style: TextStyle(fontWeight: FontWeight.bold)),
- onPressed: () {
- scaffoldKey.currentState!.openEndDrawer();
- },
- ),
- ],
- ),
- );
- }
-}
-
-class NavigationDrawerSection extends StatefulWidget {
- const NavigationDrawerSection({super.key});
-
- @override
- State<NavigationDrawerSection> createState() =>
- _NavigationDrawerSectionState();
-}
-
-class _NavigationDrawerSectionState extends State<NavigationDrawerSection> {
- int navDrawerIndex = 0;
-
- @override
- Widget build(BuildContext context) {
- return NavigationDrawer(
- onDestinationSelected: (int selectedIndex) {
- setState(() {
- navDrawerIndex = selectedIndex;
- });
- },
- selectedIndex: navDrawerIndex,
- children: <Widget>[
- Padding(
- padding: const EdgeInsets.fromLTRB(28, 16, 16, 10),
- child: Text(
- 'Mail',
- style: Theme.of(context).textTheme.titleSmall,
- ),
- ),
- ...destinations.map((ExampleDestination destination) {
- return NavigationDrawerDestination(
- label: Text(destination.label),
- icon: destination.icon,
- selectedIcon: destination.selectedIcon,
- );
- }),
- const Divider(indent: 28, endIndent: 28),
- Padding(
- padding: const EdgeInsets.fromLTRB(28, 16, 16, 10),
- child: Text(
- 'Labels',
- style: Theme.of(context).textTheme.titleSmall,
- ),
- ),
- ...labelDestinations.map((ExampleDestination destination) {
- return NavigationDrawerDestination(
- label: Text(destination.label),
- icon: destination.icon,
- selectedIcon: destination.selectedIcon,
- );
- }),
- ],
- );
- }
-}
-
-class ExampleDestination {
- const ExampleDestination(this.label, this.icon, this.selectedIcon);
-
- final String label;
- final Widget icon;
- final Widget selectedIcon;
-}
-
-const List<ExampleDestination> destinations = <ExampleDestination>[
- ExampleDestination('Inbox', Icon(Icons.inbox_outlined), Icon(Icons.inbox)),
- ExampleDestination('Outbox', Icon(Icons.send_outlined), Icon(Icons.send)),
- ExampleDestination(
- 'Favorites', Icon(Icons.favorite_outline), Icon(Icons.favorite)),
- ExampleDestination('Trash', Icon(Icons.delete_outline), Icon(Icons.delete)),
-];
-
-const List<ExampleDestination> labelDestinations = <ExampleDestination>[
- ExampleDestination(
- 'Family', Icon(Icons.bookmark_border), Icon(Icons.bookmark)),
- ExampleDestination(
- 'School', Icon(Icons.bookmark_border), Icon(Icons.bookmark)),
- ExampleDestination('Work', Icon(Icons.bookmark_border), Icon(Icons.bookmark)),
-];
-
-class NavigationRails extends StatelessWidget {
- const NavigationRails({super.key});
-
- @override
- Widget build(BuildContext context) {
- return const ComponentDecoration(
- label: 'Navigation rail',
- tooltipMessage: 'Use NavigationRail',
- child: IntrinsicWidth(
- child: SizedBox(height: 420, child: NavigationRailSection())),
- );
- }
-}
-
-class NavigationRailSection extends StatefulWidget {
- const NavigationRailSection({super.key});
-
- @override
- State<NavigationRailSection> createState() => _NavigationRailSectionState();
-}
-
-class _NavigationRailSectionState extends State<NavigationRailSection> {
- int navRailIndex = 0;
-
- @override
- Widget build(BuildContext context) {
- return NavigationRail(
- onDestinationSelected: (int selectedIndex) {
- setState(() {
- navRailIndex = selectedIndex;
- });
- },
- elevation: 4,
- leading: FloatingActionButton(
- child: const Icon(Icons.create), onPressed: () {}),
- groupAlignment: 0.0,
- selectedIndex: navRailIndex,
- labelType: NavigationRailLabelType.selected,
- destinations: <NavigationRailDestination>[
- ...destinations.map((ExampleDestination destination) {
- return NavigationRailDestination(
- label: Text(destination.label),
- icon: destination.icon,
- selectedIcon: destination.selectedIcon,
- );
- }),
- ],
- );
- }
-}
-
-class Tabs extends StatefulWidget {
- const Tabs({super.key});
-
- @override
- State<Tabs> createState() => _TabsState();
-}
-
-class _TabsState extends State<Tabs> with TickerProviderStateMixin {
- late TabController _tabController;
-
- @override
- void initState() {
- super.initState();
- _tabController = TabController(length: 3, vsync: this);
- }
-
- @override
- Widget build(BuildContext context) {
- return ComponentDecoration(
- label: 'Tabs',
- tooltipMessage: 'Use TabBar',
- child: SizedBox(
- height: 80,
- child: Scaffold(
- appBar: AppBar(
- bottom: TabBar(
- controller: _tabController,
- tabs: const <Widget>[
- Tab(
- icon: Icon(Icons.videocam_outlined),
- text: 'Video',
- iconMargin: EdgeInsets.zero,
- ),
- Tab(
- icon: Icon(Icons.photo_outlined),
- text: 'Photos',
- iconMargin: EdgeInsets.zero,
- ),
- Tab(
- icon: Icon(Icons.audiotrack_sharp),
- text: 'Audio',
- iconMargin: EdgeInsets.zero,
- ),
- ],
- ),
- ),
- ),
- ),
- );
- }
-}
-
-class TopAppBars extends StatelessWidget {
- const TopAppBars({super.key});
-
- static final List<IconButton> actions = <IconButton>[
- IconButton(icon: const Icon(Icons.attach_file), onPressed: () {}),
- IconButton(icon: const Icon(Icons.event), onPressed: () {}),
- IconButton(icon: const Icon(Icons.more_vert), onPressed: () {}),
- ];
-
- @override
- Widget build(BuildContext context) {
- return ComponentDecoration(
- label: 'Top app bars',
- tooltipMessage:
- 'Use AppBar, SliverAppBar, SliverAppBar.medium, or SliverAppBar.large',
- child: Column(
- children: <Widget>[
- AppBar(
- title: const Text('Center-aligned'),
- leading: const BackButton(),
- actions: <Widget>[
- IconButton(
- iconSize: 32,
- icon: const Icon(Icons.account_circle_outlined),
- onPressed: () {},
- ),
- ],
- centerTitle: true,
- ),
- colDivider,
- AppBar(
- title: const Text('Small'),
- leading: const BackButton(),
- actions: actions,
- centerTitle: false,
- ),
- colDivider,
- SizedBox(
- height: 100,
- child: CustomScrollView(
- slivers: <Widget>[
- SliverAppBar.medium(
- title: const Text('Medium'),
- leading: const BackButton(),
- actions: actions,
- ),
- const SliverFillRemaining(),
- ],
- ),
- ),
- colDivider,
- SizedBox(
- height: 130,
- child: CustomScrollView(
- slivers: <Widget>[
- SliverAppBar.large(
- title: const Text('Large'),
- leading: const BackButton(),
- actions: actions,
- ),
- const SliverFillRemaining(),
- ],
- ),
- ),
- ],
- ),
- );
- }
-}
-
-class Menus extends StatefulWidget {
- const Menus({super.key});
-
- @override
- State<Menus> createState() => _MenusState();
-}
-
-class _MenusState extends State<Menus> {
- final TextEditingController colorController = TextEditingController();
- final TextEditingController iconController = TextEditingController();
- IconLabel? selectedIcon = IconLabel.smile;
- ColorLabel? selectedColor;
-
- @override
- Widget build(BuildContext context) {
- final List<DropdownMenuEntry<ColorLabel>> colorEntries =
- <DropdownMenuEntry<ColorLabel>>[];
- for (final ColorLabel color in ColorLabel.values) {
- colorEntries.add(DropdownMenuEntry<ColorLabel>(
- value: color, label: color.label, enabled: color.label != 'Grey'));
- }
-
- final List<DropdownMenuEntry<IconLabel>> iconEntries =
- <DropdownMenuEntry<IconLabel>>[];
- for (final IconLabel icon in IconLabel.values) {
- iconEntries
- .add(DropdownMenuEntry<IconLabel>(value: icon, label: icon.label));
- }
-
- return ComponentDecoration(
- label: 'Menus',
- tooltipMessage: 'Use MenuAnchor or DropdownMenu<T>',
- child: Column(
- children: <Widget>[
- const Row(
- mainAxisAlignment: MainAxisAlignment.center,
- children: <Widget>[
- ButtonAnchorExample(),
- rowDivider,
- IconButtonAnchorExample(),
- ],
- ),
- colDivider,
- Wrap(
- alignment: WrapAlignment.spaceAround,
- runAlignment: WrapAlignment.center,
- crossAxisAlignment: WrapCrossAlignment.center,
- spacing: smallSpacing,
- runSpacing: smallSpacing,
- children: <Widget>[
- DropdownMenu<ColorLabel>(
- controller: colorController,
- label: const Text('Color'),
- enableFilter: true,
- dropdownMenuEntries: colorEntries,
- inputDecorationTheme: const InputDecorationTheme(filled: true),
- onSelected: (ColorLabel? color) {
- setState(() {
- selectedColor = color;
- });
- },
- ),
- DropdownMenu<IconLabel>(
- initialSelection: IconLabel.smile,
- controller: iconController,
- leadingIcon: const Icon(Icons.search),
- label: const Text('Icon'),
- dropdownMenuEntries: iconEntries,
- onSelected: (IconLabel? icon) {
- setState(() {
- selectedIcon = icon;
- });
- },
- ),
- Icon(
- selectedIcon?.icon,
- color: selectedColor?.color ?? Colors.grey.withOpacity(0.5),
- )
- ],
- ),
- ],
- ),
- );
- }
-}
-
-enum ColorLabel {
- blue('Blue', Colors.blue),
- pink('Pink', Colors.pink),
- green('Green', Colors.green),
- yellow('Yellow', Colors.yellow),
- grey('Grey', Colors.grey);
-
- const ColorLabel(this.label, this.color);
- final String label;
- final Color color;
-}
-
-enum IconLabel {
- smile('Smile', Icons.sentiment_satisfied_outlined),
- cloud(
- 'Cloud',
- Icons.cloud_outlined,
- ),
- brush('Brush', Icons.brush_outlined),
- heart('Heart', Icons.favorite);
-
- const IconLabel(this.label, this.icon);
- final String label;
- final IconData icon;
-}
-
-class Sliders extends StatefulWidget {
- const Sliders({super.key});
-
- @override
- State<Sliders> createState() => _SlidersState();
-}
-
-class _SlidersState extends State<Sliders> {
- double sliderValue0 = 30.0;
- double sliderValue1 = 20.0;
-
- @override
- Widget build(BuildContext context) {
- return ComponentDecoration(
- label: 'Sliders',
- tooltipMessage: 'Use Slider or RangeSlider',
- child: Column(
- children: <Widget>[
- Slider(
- max: 100,
- value: sliderValue0,
- onChanged: (double value) {
- setState(() {
- sliderValue0 = value;
- });
- },
- ),
- const SizedBox(height: 20),
- Slider(
- max: 100,
- divisions: 5,
- value: sliderValue1,
- label: sliderValue1.round().toString(),
- onChanged: (double value) {
- setState(() {
- sliderValue1 = value;
- });
- },
- ),
- ],
- ));
- }
-}
-
-class ComponentDecoration extends StatefulWidget {
- const ComponentDecoration({
- super.key,
- required this.label,
- required this.child,
- this.tooltipMessage = '',
- });
-
- final String label;
- final Widget child;
- final String? tooltipMessage;
-
- @override
- State<ComponentDecoration> createState() => _ComponentDecorationState();
-}
-
-class _ComponentDecorationState extends State<ComponentDecoration> {
- final FocusNode focusNode = FocusNode();
-
- @override
- Widget build(BuildContext context) {
- return RepaintBoundary(
- child: Padding(
- padding: const EdgeInsets.symmetric(vertical: smallSpacing),
- child: Column(
- children: <Widget>[
- Row(
- mainAxisAlignment: MainAxisAlignment.center,
- children: <Widget>[
- Text(widget.label,
- style: Theme.of(context).textTheme.titleSmall),
- Tooltip(
- message: widget.tooltipMessage,
- child: const Padding(
- padding: EdgeInsets.symmetric(horizontal: 5.0),
- child: Icon(Icons.info_outline, size: 16)),
- ),
- ],
- ),
- ConstrainedBox(
- constraints:
- const BoxConstraints.tightFor(width: widthConstraint),
- // Tapping within the a component card should request focus
- // for that component's children.
- child: Focus(
- focusNode: focusNode,
- canRequestFocus: true,
- child: GestureDetector(
- onTapDown: (_) {
- focusNode.requestFocus();
- },
- behavior: HitTestBehavior.opaque,
- child: Card(
- elevation: 0,
- shape: RoundedRectangleBorder(
- side: BorderSide(
- color: Theme.of(context).colorScheme.outlineVariant,
- ),
- borderRadius: const BorderRadius.all(Radius.circular(12)),
- ),
- child: Padding(
- padding: const EdgeInsets.symmetric(
- horizontal: 5.0, vertical: 20.0),
- child: Center(
- child: widget.child,
- ),
- ),
- ),
- ),
- ),
- ),
- ],
- ),
- ),
- );
- }
-}
-
-class ComponentGroupDecoration extends StatelessWidget {
- const ComponentGroupDecoration(
- {super.key, required this.label, required this.children});
-
- final String label;
- final List<Widget> children;
-
- @override
- Widget build(BuildContext context) {
- // Fully traverse this component group before moving on
- return FocusTraversalGroup(
- child: Card(
- margin: EdgeInsets.zero,
- elevation: 0,
- color: Theme.of(context).colorScheme.surfaceVariant.withOpacity(0.3),
- child: Padding(
- padding: const EdgeInsets.symmetric(vertical: 20.0),
- child: Center(
- child: Column(
- children: <Widget>[
- Text(label, style: Theme.of(context).textTheme.titleLarge),
- colDivider,
- ...children
- ],
- ),
- ),
- ),
- ),
- );
+ return const TwoColumnMaterial3Components();
}
}
diff --git a/dev/benchmarks/macrobenchmarks/lib/src/web/bench_material_3_semantics.dart b/dev/benchmarks/macrobenchmarks/lib/src/web/bench_material_3_semantics.dart
new file mode 100644
index 0000000..8b23080
--- /dev/null
+++ b/dev/benchmarks/macrobenchmarks/lib/src/web/bench_material_3_semantics.dart
@@ -0,0 +1,147 @@
+// Copyright 2014 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'dart:async';
+
+import 'package:flutter/foundation.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/scheduler.dart';
+import 'package:flutter/semantics.dart';
+
+import 'material3.dart';
+import 'recorder.dart';
+
+/// Measures the cost of semantics when constructing screens containing
+/// Material 3 widgets.
+class BenchMaterial3Semantics extends WidgetBuildRecorder {
+ BenchMaterial3Semantics() : super(name: benchmarkName);
+
+ static const String benchmarkName = 'bench_material3_semantics';
+
+ @override
+ Future<void> setUpAll() async {
+ FlutterTimeline.debugCollectionEnabled = true;
+ super.setUpAll();
+ SemanticsBinding.instance.ensureSemantics();
+ }
+
+ @override
+ Future<void> tearDownAll() async {
+ FlutterTimeline.debugReset();
+ }
+
+ @override
+ void frameDidDraw() {
+ // Only record frames that show the widget. Frames that remove the widget
+ // are not interesting.
+ if (showWidget) {
+ final AggregatedTimings timings = FlutterTimeline.debugCollect();
+ final AggregatedTimedBlock semanticsBlock = timings.getAggregated('SEMANTICS');
+ final AggregatedTimedBlock getFragmentBlock = timings.getAggregated('Semantics.GetFragment');
+ final AggregatedTimedBlock compileChildrenBlock = timings.getAggregated('Semantics.compileChildren');
+ profile!.addTimedBlock(semanticsBlock, reported: true);
+ profile!.addTimedBlock(getFragmentBlock, reported: true);
+ profile!.addTimedBlock(compileChildrenBlock, reported: true);
+ }
+
+ super.frameDidDraw();
+ FlutterTimeline.debugReset();
+ }
+
+ @override
+ Widget createWidget() {
+ return const SingleColumnMaterial3Components();
+ }
+}
+
+/// Measures the cost of semantics when scrolling screens containing Material 3
+/// widgets.
+///
+/// The implementation uses a ListView that jumps the scroll position between
+/// 0 and 1 every frame. Such a small delta is not enough for lazy rendering to
+/// add/remove widgets, but its enough to trigger the framework to recompute
+/// some of the semantics.
+///
+/// The expected output numbers of this benchmarks should be very small as
+/// scrolling a list view should be a matter of shifting some widgets and
+/// updating the projected clip imposed by the viewport. As of June 2023, the
+/// numbers are not great. Semantics consumes >50% of frame time.
+class BenchMaterial3ScrollSemantics extends WidgetRecorder {
+ BenchMaterial3ScrollSemantics() : super(name: benchmarkName);
+
+ static const String benchmarkName = 'bench_material3_scroll_semantics';
+
+ @override
+ Future<void> setUpAll() async {
+ FlutterTimeline.debugCollectionEnabled = true;
+ super.setUpAll();
+ SemanticsBinding.instance.ensureSemantics();
+ }
+
+ @override
+ Future<void> tearDownAll() async {
+ FlutterTimeline.debugReset();
+ }
+
+ @override
+ void frameDidDraw() {
+ final AggregatedTimings timings = FlutterTimeline.debugCollect();
+ final AggregatedTimedBlock semanticsBlock = timings.getAggregated('SEMANTICS');
+ final AggregatedTimedBlock getFragmentBlock = timings.getAggregated('Semantics.GetFragment');
+ final AggregatedTimedBlock compileChildrenBlock = timings.getAggregated('Semantics.compileChildren');
+ profile!.addTimedBlock(semanticsBlock, reported: true);
+ profile!.addTimedBlock(getFragmentBlock, reported: true);
+ profile!.addTimedBlock(compileChildrenBlock, reported: true);
+
+ super.frameDidDraw();
+ FlutterTimeline.debugReset();
+ }
+
+ @override
+ Widget createWidget() => _ScrollTest();
+}
+
+class _ScrollTest extends StatefulWidget {
+ @override
+ State<_ScrollTest> createState() => _ScrollTestState();
+}
+
+class _ScrollTestState extends State<_ScrollTest> with SingleTickerProviderStateMixin {
+ late final Ticker ticker;
+ late final ScrollController scrollController;
+
+ @override
+ void initState() {
+ super.initState();
+
+ scrollController = ScrollController();
+
+ bool forward = true;
+
+ // A one-off timer is necessary to allow the framework to measure the
+ // available scroll extents before the scroll controller can be exercised
+ // to change the scroll position.
+ Timer.run(() {
+ ticker = createTicker((_) {
+ scrollController.jumpTo(forward ? 1 : 0);
+ forward = !forward;
+ });
+ ticker.start();
+ });
+ }
+
+ @override
+ void dispose() {
+ ticker.dispose();
+ scrollController.dispose();
+ super.dispose();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return SingleColumnMaterial3Components(
+ scrollController: scrollController,
+ );
+ }
+}
diff --git a/dev/benchmarks/macrobenchmarks/lib/src/web/bench_mouse_region_grid_scroll.dart b/dev/benchmarks/macrobenchmarks/lib/src/web/bench_mouse_region_grid_scroll.dart
index 6eabda4..7fbb80e 100644
--- a/dev/benchmarks/macrobenchmarks/lib/src/web/bench_mouse_region_grid_scroll.dart
+++ b/dev/benchmarks/macrobenchmarks/lib/src/web/bench_mouse_region_grid_scroll.dart
@@ -130,10 +130,10 @@
final int frameDurationMs = fullFrameDuration.inMilliseconds;
final int fullFrames = duration.inMilliseconds ~/ frameDurationMs;
- final Offset fullFrameOffset = offset * ((frameDurationMs as double) / durationMs);
+ final Offset fullFrameOffset = offset * (frameDurationMs.toDouble() / durationMs);
final Duration finalFrameDuration = duration - fullFrameDuration * fullFrames;
- final Offset finalFrameOffset = offset - fullFrameOffset * (fullFrames as double);
+ final Offset finalFrameOffset = offset - fullFrameOffset * fullFrames.toDouble();
await gesture.down(start, timeStamp: currentTime);
diff --git a/dev/benchmarks/macrobenchmarks/lib/src/web/bench_platform_view_infinite_scroll.dart b/dev/benchmarks/macrobenchmarks/lib/src/web/bench_platform_view_infinite_scroll.dart
index b4e9d85..3781274 100644
--- a/dev/benchmarks/macrobenchmarks/lib/src/web/bench_platform_view_infinite_scroll.dart
+++ b/dev/benchmarks/macrobenchmarks/lib/src/web/bench_platform_view_infinite_scroll.dart
@@ -3,7 +3,6 @@
// found in the LICENSE file.
import 'dart:async';
-import 'dart:js_interop';
import 'dart:ui_web' as ui_web;
import 'package:flutter/material.dart';
@@ -16,16 +15,16 @@
void _registerFactory() {
ui_web.platformViewRegistry.registerViewFactory(benchmarkViewType, (int viewId) {
final web.HTMLElement htmlElement =
- web.document.createElement('div'.toJS) as web.HTMLDivElement;
- htmlElement.id = '${benchmarkViewType}_$viewId'.toJS;
- htmlElement.innerText = 'Google'.toJS;
+ web.document.createElement('div') as web.HTMLDivElement;
+ htmlElement.id = '${benchmarkViewType}_$viewId';
+ htmlElement.innerText = 'Google';
htmlElement.style
- ..setProperty('width'.toJS, '100%'.toJS)
- ..setProperty('height'.toJS, '100%'.toJS)
- ..setProperty('color'.toJS, 'black'.toJS)
- ..setProperty('backgroundColor'.toJS, 'rgba(0, 255, 0, .5)'.toJS)
- ..setProperty('textAlign'.toJS, 'center'.toJS)
- ..setProperty('border'.toJS, '1px solid black'.toJS);
+ ..setProperty('width', '100%')
+ ..setProperty('height', '100%')
+ ..setProperty('color', 'black')
+ ..setProperty('backgroundColor', 'rgba(0, 255, 0, .5)')
+ ..setProperty('textAlign', 'center')
+ ..setProperty('border', '1px solid black');
return htmlElement;
});
}
diff --git a/dev/benchmarks/macrobenchmarks/lib/src/web/bench_text_layout.dart b/dev/benchmarks/macrobenchmarks/lib/src/web/bench_text_layout.dart
index e1156dd..6788ec8 100644
--- a/dev/benchmarks/macrobenchmarks/lib/src/web/bench_text_layout.dart
+++ b/dev/benchmarks/macrobenchmarks/lib/src/web/bench_text_layout.dart
@@ -203,6 +203,7 @@
@override
Future<void> setUpAll() async {
+ super.setUpAll();
registerEngineBenchmarkValueListener('text_layout', (num value) {
_textLayoutMicros += value;
});
diff --git a/dev/benchmarks/macrobenchmarks/lib/src/web/material3.dart b/dev/benchmarks/macrobenchmarks/lib/src/web/material3.dart
new file mode 100644
index 0000000..1ec8ae1
--- /dev/null
+++ b/dev/benchmarks/macrobenchmarks/lib/src/web/material3.dart
@@ -0,0 +1,2369 @@
+// Copyright 2014 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+
+const SizedBox rowDivider = SizedBox(width: 20);
+const SizedBox colDivider = SizedBox(height: 10);
+const double smallSpacing = 10.0;
+const double cardWidth = 115;
+const double widthConstraint = 450;
+final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
+
+class SingleColumnMaterial3Components extends StatelessWidget {
+ const SingleColumnMaterial3Components({
+ super.key,
+ this.scrollController,
+ });
+
+ final ScrollController? scrollController;
+
+ @override
+ Widget build(BuildContext context) {
+ return MaterialApp(
+ home: Scaffold(
+ key: scaffoldKey,
+ body: ListView(
+ controller: scrollController,
+ children: <Widget>[
+ const Actions(),
+ colDivider,
+ const Communication(),
+ colDivider,
+ const Containment(),
+ colDivider,
+ Navigation(scaffoldKey: scaffoldKey),
+ colDivider,
+ const Selection(),
+ colDivider,
+ const TextInputs(),
+ colDivider,
+ Navigation(scaffoldKey: scaffoldKey),
+ colDivider,
+ const Selection(),
+ colDivider,
+ const TextInputs(),
+ ],
+ ),
+ ),
+ );
+ }
+}
+
+class TwoColumnMaterial3Components extends StatefulWidget {
+ const TwoColumnMaterial3Components({super.key});
+
+ @override
+ State<TwoColumnMaterial3Components> createState() => _TwoColumnMaterial3ComponentsState();
+}
+
+class _TwoColumnMaterial3ComponentsState extends State<TwoColumnMaterial3Components> {
+ @override
+ Widget build(BuildContext context) {
+ return MaterialApp(
+ home: Scaffold(
+ key: scaffoldKey,
+ body: Row(
+ children: <Widget>[
+ Expanded(
+ child: FirstComponentList(
+ showNavBottomBar: true,
+ scaffoldKey: scaffoldKey,
+ showSecondList: true,
+ ),
+ ),
+ Expanded(
+ child: SecondComponentList(scaffoldKey: scaffoldKey),
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+}
+
+class FirstComponentList extends StatelessWidget {
+ const FirstComponentList({
+ super.key,
+ required this.showNavBottomBar,
+ required this.scaffoldKey,
+ required this.showSecondList,
+ });
+
+ final bool showNavBottomBar;
+ final GlobalKey<ScaffoldState> scaffoldKey;
+ final bool showSecondList;
+
+ @override
+ Widget build(BuildContext context) {
+ // Fully traverse this list before moving on.
+ return FocusTraversalGroup(
+ child: ListView(
+ padding: showSecondList
+ ? const EdgeInsetsDirectional.only(end: smallSpacing)
+ : EdgeInsets.zero,
+ children: <Widget>[
+ const Actions(),
+ colDivider,
+ const Communication(),
+ colDivider,
+ const Containment(),
+ if (!showSecondList) ...<Widget>[
+ colDivider,
+ Navigation(scaffoldKey: scaffoldKey),
+ colDivider,
+ const Selection(),
+ colDivider,
+ const TextInputs()
+ ],
+ ],
+ ),
+ );
+ }
+}
+
+class SecondComponentList extends StatelessWidget {
+ const SecondComponentList({
+ super.key,
+ required this.scaffoldKey,
+ });
+
+ final GlobalKey<ScaffoldState> scaffoldKey;
+
+ @override
+ Widget build(BuildContext context) {
+ // Fully traverse this list before moving on.
+ return FocusTraversalGroup(
+ child: ListView(
+ padding: const EdgeInsetsDirectional.only(end: smallSpacing),
+ children: <Widget>[
+ Navigation(scaffoldKey: scaffoldKey),
+ colDivider,
+ const Selection(),
+ colDivider,
+ const TextInputs(),
+ ],
+ ),
+ );
+ }
+}
+
+class Actions extends StatelessWidget {
+ const Actions({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return const ComponentGroupDecoration(label: 'Actions', children: <Widget>[
+ Buttons(),
+ FloatingActionButtons(),
+ IconToggleButtons(),
+ SegmentedButtons(),
+ ]);
+ }
+}
+
+class Communication extends StatelessWidget {
+ const Communication({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return const ComponentGroupDecoration(label: 'Communication', children: <Widget>[
+ NavigationBars(
+ selectedIndex: 1,
+ isExampleBar: true,
+ isBadgeExample: true,
+ ),
+ ProgressIndicators(),
+ SnackBarSection(),
+ ]);
+ }
+}
+
+class Containment extends StatelessWidget {
+ const Containment({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return const ComponentGroupDecoration(label: 'Containment', children: <Widget>[
+ BottomSheetSection(),
+ Cards(),
+ Dialogs(),
+ Dividers(),
+ ]);
+ }
+}
+
+class Navigation extends StatelessWidget {
+ const Navigation({super.key, required this.scaffoldKey});
+
+ final GlobalKey<ScaffoldState> scaffoldKey;
+
+ @override
+ Widget build(BuildContext context) {
+ return ComponentGroupDecoration(label: 'Navigation', children: <Widget>[
+ const BottomAppBars(),
+ const NavigationBars(
+ selectedIndex: 0,
+ isExampleBar: true,
+ ),
+ NavigationDrawers(scaffoldKey: scaffoldKey),
+ const NavigationRails(),
+ const Tabs(),
+ const TopAppBars(),
+ ]);
+ }
+}
+
+class Selection extends StatelessWidget {
+ const Selection({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return const ComponentGroupDecoration(label: 'Selection', children: <Widget>[
+ Checkboxes(),
+ Chips(),
+ Menus(),
+ Radios(),
+ Sliders(),
+ Switches(),
+ ]);
+ }
+}
+
+class TextInputs extends StatelessWidget {
+ const TextInputs({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return const ComponentGroupDecoration(
+ label: 'Text inputs',
+ children: <Widget>[TextFields()],
+ );
+ }
+}
+
+class Buttons extends StatefulWidget {
+ const Buttons({super.key});
+
+ @override
+ State<Buttons> createState() => _ButtonsState();
+}
+
+class _ButtonsState extends State<Buttons> {
+ @override
+ Widget build(BuildContext context) {
+ return const ComponentDecoration(
+ label: 'Common buttons',
+ tooltipMessage:
+ 'Use ElevatedButton, FilledButton, FilledButton.tonal, OutlinedButton, or TextButton',
+ child: SingleChildScrollView(
+ scrollDirection: Axis.horizontal,
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceAround,
+ children: <Widget>[
+ ButtonsWithoutIcon(isDisabled: false),
+ ButtonsWithIcon(),
+ ButtonsWithoutIcon(isDisabled: true),
+ ],
+ ),
+ ),
+ );
+ }
+}
+
+class ButtonsWithoutIcon extends StatelessWidget {
+ const ButtonsWithoutIcon({super.key, required this.isDisabled});
+
+ final bool isDisabled;
+
+ @override
+ Widget build(BuildContext context) {
+ return Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 5.0),
+ child: IntrinsicWidth(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.stretch,
+ children: <Widget>[
+ ElevatedButton(
+ onPressed: isDisabled ? null : () {},
+ child: const Text('Elevated'),
+ ),
+ colDivider,
+ FilledButton(
+ onPressed: isDisabled ? null : () {},
+ child: const Text('Filled'),
+ ),
+ colDivider,
+ FilledButton.tonal(
+ onPressed: isDisabled ? null : () {},
+ child: const Text('Filled tonal'),
+ ),
+ colDivider,
+ OutlinedButton(
+ onPressed: isDisabled ? null : () {},
+ child: const Text('Outlined'),
+ ),
+ colDivider,
+ TextButton(
+ onPressed: isDisabled ? null : () {},
+ child: const Text('Text'),
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+}
+
+class ButtonsWithIcon extends StatelessWidget {
+ const ButtonsWithIcon({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 10.0),
+ child: IntrinsicWidth(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.stretch,
+ children: <Widget>[
+ ElevatedButton.icon(
+ onPressed: () {},
+ icon: const Icon(Icons.add),
+ label: const Text('Icon'),
+ ),
+ colDivider,
+ FilledButton.icon(
+ onPressed: () {},
+ label: const Text('Icon'),
+ icon: const Icon(Icons.add),
+ ),
+ colDivider,
+ FilledButton.tonalIcon(
+ onPressed: () {},
+ label: const Text('Icon'),
+ icon: const Icon(Icons.add),
+ ),
+ colDivider,
+ OutlinedButton.icon(
+ onPressed: () {},
+ icon: const Icon(Icons.add),
+ label: const Text('Icon'),
+ ),
+ colDivider,
+ TextButton.icon(
+ onPressed: () {},
+ icon: const Icon(Icons.add),
+ label: const Text('Icon'),
+ )
+ ],
+ ),
+ ),
+ );
+ }
+}
+
+class FloatingActionButtons extends StatelessWidget {
+ const FloatingActionButtons({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return ComponentDecoration(
+ label: 'Floating action buttons',
+ tooltipMessage:
+ 'Use FloatingActionButton or FloatingActionButton.extended',
+ child: Wrap(
+ crossAxisAlignment: WrapCrossAlignment.center,
+ runSpacing: smallSpacing,
+ spacing: smallSpacing,
+ children: <Widget>[
+ FloatingActionButton.small(
+ onPressed: () {},
+ tooltip: 'Small',
+ child: const Icon(Icons.add),
+ ),
+ FloatingActionButton.extended(
+ onPressed: () {},
+ tooltip: 'Extended',
+ icon: const Icon(Icons.add),
+ label: const Text('Create'),
+ ),
+ FloatingActionButton(
+ onPressed: () {},
+ tooltip: 'Standard',
+ child: const Icon(Icons.add),
+ ),
+ FloatingActionButton.large(
+ onPressed: () {},
+ tooltip: 'Large',
+ child: const Icon(Icons.add),
+ ),
+ ],
+ ),
+ );
+ }
+}
+
+class Cards extends StatelessWidget {
+ const Cards({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return ComponentDecoration(
+ label: 'Cards',
+ tooltipMessage: 'Use Card',
+ child: Wrap(
+ alignment: WrapAlignment.spaceEvenly,
+ children: <Widget>[
+ SizedBox(
+ width: cardWidth,
+ child: Card(
+ child: Container(
+ padding: const EdgeInsets.fromLTRB(10, 5, 5, 10),
+ child: Column(
+ children: <Widget>[
+ Align(
+ alignment: Alignment.topRight,
+ child: IconButton(
+ icon: const Icon(Icons.more_vert),
+ onPressed: () {},
+ ),
+ ),
+ const SizedBox(height: 20),
+ const Align(
+ alignment: Alignment.bottomLeft,
+ child: Text('Elevated'),
+ )
+ ],
+ ),
+ ),
+ ),
+ ),
+ SizedBox(
+ width: cardWidth,
+ child: Card(
+ color: Theme.of(context).colorScheme.surfaceVariant,
+ elevation: 0,
+ child: Container(
+ padding: const EdgeInsets.fromLTRB(10, 5, 5, 10),
+ child: Column(
+ children: <Widget>[
+ Align(
+ alignment: Alignment.topRight,
+ child: IconButton(
+ icon: const Icon(Icons.more_vert),
+ onPressed: () {},
+ ),
+ ),
+ const SizedBox(height: 20),
+ const Align(
+ alignment: Alignment.bottomLeft,
+ child: Text('Filled'),
+ )
+ ],
+ ),
+ ),
+ ),
+ ),
+ SizedBox(
+ width: cardWidth,
+ child: Card(
+ elevation: 0,
+ shape: RoundedRectangleBorder(
+ side: BorderSide(
+ color: Theme.of(context).colorScheme.outline,
+ ),
+ borderRadius: const BorderRadius.all(Radius.circular(12)),
+ ),
+ child: Container(
+ padding: const EdgeInsets.fromLTRB(10, 5, 5, 10),
+ child: Column(
+ children: <Widget>[
+ Align(
+ alignment: Alignment.topRight,
+ child: IconButton(
+ icon: const Icon(Icons.more_vert),
+ onPressed: () {},
+ ),
+ ),
+ const SizedBox(height: 20),
+ const Align(
+ alignment: Alignment.bottomLeft,
+ child: Text('Outlined'),
+ )
+ ],
+ ),
+ ),
+ ),
+ ),
+ ],
+ ),
+ );
+ }
+}
+
+class _ClearButton extends StatelessWidget {
+ const _ClearButton({required this.controller});
+
+ final TextEditingController controller;
+
+ @override
+ Widget build(BuildContext context) => IconButton(
+ icon: const Icon(Icons.clear),
+ onPressed: () => controller.clear(),
+ );
+}
+
+class TextFields extends StatefulWidget {
+ const TextFields({super.key});
+
+ @override
+ State<TextFields> createState() => _TextFieldsState();
+}
+
+class _TextFieldsState extends State<TextFields> {
+ final TextEditingController _controllerFilled = TextEditingController();
+ final TextEditingController _controllerOutlined = TextEditingController();
+
+ @override
+ Widget build(BuildContext context) {
+ return ComponentDecoration(
+ label: 'Text fields',
+ tooltipMessage: 'Use TextField with different InputDecoration',
+ child: Column(
+ children: <Widget>[
+ Padding(
+ padding: const EdgeInsets.all(smallSpacing),
+ child: TextField(
+ controller: _controllerFilled,
+ decoration: InputDecoration(
+ prefixIcon: const Icon(Icons.search),
+ suffixIcon: _ClearButton(controller: _controllerFilled),
+ labelText: 'Filled',
+ hintText: 'hint text',
+ helperText: 'supporting text',
+ filled: true,
+ ),
+ ),
+ ),
+ Padding(
+ padding: const EdgeInsets.all(smallSpacing),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: <Widget>[
+ Flexible(
+ child: SizedBox(
+ width: 200,
+ child: TextField(
+ maxLength: 10,
+ maxLengthEnforcement: MaxLengthEnforcement.none,
+ controller: _controllerFilled,
+ decoration: InputDecoration(
+ prefixIcon: const Icon(Icons.search),
+ suffixIcon: _ClearButton(controller: _controllerFilled),
+ labelText: 'Filled',
+ hintText: 'hint text',
+ helperText: 'supporting text',
+ filled: true,
+ errorText: 'error text',
+ ),
+ ),
+ ),
+ ),
+ const SizedBox(width: smallSpacing),
+ Flexible(
+ child: SizedBox(
+ width: 200,
+ child: TextField(
+ controller: _controllerFilled,
+ enabled: false,
+ decoration: InputDecoration(
+ prefixIcon: const Icon(Icons.search),
+ suffixIcon: _ClearButton(controller: _controllerFilled),
+ labelText: 'Disabled',
+ hintText: 'hint text',
+ helperText: 'supporting text',
+ filled: true,
+ ),
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ Padding(
+ padding: const EdgeInsets.all(smallSpacing),
+ child: TextField(
+ controller: _controllerOutlined,
+ decoration: InputDecoration(
+ prefixIcon: const Icon(Icons.search),
+ suffixIcon: _ClearButton(controller: _controllerOutlined),
+ labelText: 'Outlined',
+ hintText: 'hint text',
+ helperText: 'supporting text',
+ border: const OutlineInputBorder(),
+ ),
+ ),
+ ),
+ Padding(
+ padding: const EdgeInsets.all(smallSpacing),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: <Widget>[
+ Flexible(
+ child: SizedBox(
+ width: 200,
+ child: TextField(
+ controller: _controllerOutlined,
+ decoration: InputDecoration(
+ prefixIcon: const Icon(Icons.search),
+ suffixIcon:
+ _ClearButton(controller: _controllerOutlined),
+ labelText: 'Outlined',
+ hintText: 'hint text',
+ helperText: 'supporting text',
+ errorText: 'error text',
+ border: const OutlineInputBorder(),
+ filled: true,
+ ),
+ ),
+ ),
+ ),
+ const SizedBox(width: smallSpacing),
+ Flexible(
+ child: SizedBox(
+ width: 200,
+ child: TextField(
+ controller: _controllerOutlined,
+ enabled: false,
+ decoration: InputDecoration(
+ prefixIcon: const Icon(Icons.search),
+ suffixIcon:
+ _ClearButton(controller: _controllerOutlined),
+ labelText: 'Disabled',
+ hintText: 'hint text',
+ helperText: 'supporting text',
+ border: const OutlineInputBorder(),
+ filled: true,
+ ),
+ ),
+ ),
+ ),
+ ])),
+ ],
+ ),
+ );
+ }
+}
+
+class Dialogs extends StatefulWidget {
+ const Dialogs({super.key});
+
+ @override
+ State<Dialogs> createState() => _DialogsState();
+}
+
+class _DialogsState extends State<Dialogs> {
+ void openDialog(BuildContext context) {
+ showDialog<void>(
+ context: context,
+ builder: (BuildContext context) => AlertDialog(
+ title: const Text('What is a dialog?'),
+ content: const Text(
+ 'A dialog is a type of modal window that appears in front of app content to provide critical information, or prompt for a decision to be made.'),
+ actions: <Widget>[
+ TextButton(
+ child: const Text('Okay'),
+ onPressed: () => Navigator.of(context).pop(),
+ ),
+ FilledButton(
+ child: const Text('Dismiss'),
+ onPressed: () => Navigator.of(context).pop(),
+ ),
+ ],
+ ),
+ );
+ }
+
+ void openFullscreenDialog(BuildContext context) {
+ showDialog<void>(
+ context: context,
+ builder: (BuildContext context) => Dialog.fullscreen(
+ child: Padding(
+ padding: const EdgeInsets.all(20.0),
+ child: Scaffold(
+ appBar: AppBar(
+ title: const Text('Full-screen dialog'),
+ centerTitle: false,
+ leading: IconButton(
+ icon: const Icon(Icons.close),
+ onPressed: () => Navigator.of(context).pop(),
+ ),
+ actions: <Widget>[
+ TextButton(
+ child: const Text('Close'),
+ onPressed: () => Navigator.of(context).pop(),
+ ),
+ ],
+ ),
+ ),
+ ),
+ ),
+ );
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return ComponentDecoration(
+ label: 'Dialog',
+ tooltipMessage:
+ 'Use showDialog with Dialog.fullscreen, AlertDialog, or SimpleDialog',
+ child: Wrap(
+ alignment: WrapAlignment.spaceBetween,
+ children: <Widget>[
+ TextButton(
+ child: const Text(
+ 'Show dialog',
+ style: TextStyle(fontWeight: FontWeight.bold),
+ ),
+ onPressed: () => openDialog(context),
+ ),
+ TextButton(
+ child: const Text(
+ 'Show full-screen dialog',
+ style: TextStyle(fontWeight: FontWeight.bold),
+ ),
+ onPressed: () => openFullscreenDialog(context),
+ ),
+ ],
+ ),
+ );
+ }
+}
+
+class Dividers extends StatelessWidget {
+ const Dividers({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return const ComponentDecoration(
+ label: 'Dividers',
+ tooltipMessage: 'Use Divider or VerticalDivider',
+ child: Column(
+ children: <Widget>[
+ Divider(key: Key('divider')),
+ ],
+ ),
+ );
+ }
+}
+
+class Switches extends StatelessWidget {
+ const Switches({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return const ComponentDecoration(
+ label: 'Switches',
+ tooltipMessage: 'Use SwitchListTile or Switch',
+ child: Column(
+ children: <Widget>[
+ SwitchRow(isEnabled: true),
+ SwitchRow(isEnabled: false),
+ ],
+ ),
+ );
+ }
+}
+
+class SwitchRow extends StatefulWidget {
+ const SwitchRow({super.key, required this.isEnabled});
+
+ final bool isEnabled;
+
+ @override
+ State<SwitchRow> createState() => _SwitchRowState();
+}
+
+class _SwitchRowState extends State<SwitchRow> {
+ bool value0 = false;
+ bool value1 = true;
+
+ final MaterialStateProperty<Icon?> thumbIcon =
+ MaterialStateProperty.resolveWith<Icon?>((Set<MaterialState> states) {
+ if (states.contains(MaterialState.selected)) {
+ return const Icon(Icons.check);
+ }
+ return const Icon(Icons.close);
+ });
+
+ @override
+ Widget build(BuildContext context) {
+ return Row(
+ mainAxisAlignment: MainAxisAlignment.spaceEvenly,
+ children: <Widget>[
+ Switch(
+ value: value0,
+ onChanged: widget.isEnabled
+ ? (bool value) {
+ setState(() {
+ value0 = value;
+ });
+ }
+ : null,
+ ),
+ Switch(
+ thumbIcon: thumbIcon,
+ value: value1,
+ onChanged: widget.isEnabled
+ ? (bool value) {
+ setState(() {
+ value1 = value;
+ });
+ }
+ : null,
+ ),
+ ],
+ );
+ }
+}
+
+class Checkboxes extends StatefulWidget {
+ const Checkboxes({super.key});
+
+ @override
+ State<Checkboxes> createState() => _CheckboxesState();
+}
+
+class _CheckboxesState extends State<Checkboxes> {
+ bool? isChecked0 = true;
+ bool? isChecked1;
+ bool? isChecked2 = false;
+
+ @override
+ Widget build(BuildContext context) {
+ return ComponentDecoration(
+ label: 'Checkboxes',
+ tooltipMessage: 'Use CheckboxListTile or Checkbox',
+ child: Column(
+ children: <Widget>[
+ CheckboxListTile(
+ tristate: true,
+ value: isChecked0,
+ title: const Text('Option 1'),
+ onChanged: (bool? value) {
+ setState(() {
+ isChecked0 = value;
+ });
+ },
+ ),
+ CheckboxListTile(
+ tristate: true,
+ value: isChecked1,
+ title: const Text('Option 2'),
+ onChanged: (bool? value) {
+ setState(() {
+ isChecked1 = value;
+ });
+ },
+ ),
+ CheckboxListTile(
+ tristate: true,
+ value: isChecked2,
+ title: const Text('Option 3'),
+ onChanged: (bool? value) {
+ setState(() {
+ isChecked2 = value;
+ });
+ },
+ ),
+ const CheckboxListTile(
+ tristate: true,
+ title: Text('Option 4'),
+ value: true,
+ onChanged: null,
+ ),
+ ],
+ ),
+ );
+ }
+}
+
+enum Value { first, second }
+
+class Radios extends StatefulWidget {
+ const Radios({super.key});
+
+ @override
+ State<Radios> createState() => _RadiosState();
+}
+
+enum Options { option1, option2, option3 }
+
+class _RadiosState extends State<Radios> {
+ Options? _selectedOption = Options.option1;
+
+ @override
+ Widget build(BuildContext context) {
+ return ComponentDecoration(
+ label: 'Radio buttons',
+ tooltipMessage: 'Use RadioListTile<T> or Radio<T>',
+ child: Column(
+ children: <Widget>[
+ RadioListTile<Options>(
+ title: const Text('Option 1'),
+ value: Options.option1,
+ groupValue: _selectedOption,
+ onChanged: (Options? value) {
+ setState(() {
+ _selectedOption = value;
+ });
+ },
+ ),
+ RadioListTile<Options>(
+ title: const Text('Option 2'),
+ value: Options.option2,
+ groupValue: _selectedOption,
+ onChanged: (Options? value) {
+ setState(() {
+ _selectedOption = value;
+ });
+ },
+ ),
+ RadioListTile<Options>(
+ title: const Text('Option 3'),
+ value: Options.option3,
+ groupValue: _selectedOption,
+ onChanged: null,
+ ),
+ ],
+ ),
+ );
+ }
+}
+
+class ProgressIndicators extends StatefulWidget {
+ const ProgressIndicators({super.key});
+
+ @override
+ State<ProgressIndicators> createState() => _ProgressIndicatorsState();
+}
+
+class _ProgressIndicatorsState extends State<ProgressIndicators> {
+ bool playProgressIndicator = false;
+
+ @override
+ Widget build(BuildContext context) {
+ final double? progressValue = playProgressIndicator ? null : 0.7;
+
+ return ComponentDecoration(
+ label: 'Progress indicators',
+ tooltipMessage:
+ 'Use CircularProgressIndicator or LinearProgressIndicator',
+ child: Column(
+ children: <Widget>[
+ Row(
+ children: <Widget>[
+ IconButton(
+ isSelected: playProgressIndicator,
+ selectedIcon: const Icon(Icons.pause),
+ icon: const Icon(Icons.play_arrow),
+ onPressed: () {
+ setState(() {
+ playProgressIndicator = !playProgressIndicator;
+ });
+ },
+ ),
+ Expanded(
+ child: Row(
+ children: <Widget>[
+ rowDivider,
+ CircularProgressIndicator(
+ value: progressValue,
+ ),
+ rowDivider,
+ Expanded(
+ child: LinearProgressIndicator(
+ value: progressValue,
+ ),
+ ),
+ rowDivider,
+ ],
+ ),
+ ),
+ ],
+ ),
+ ],
+ ),
+ );
+ }
+}
+
+const List<NavigationDestination> appBarDestinations = <NavigationDestination>[
+ NavigationDestination(
+ tooltip: '',
+ icon: Icon(Icons.widgets_outlined),
+ label: 'Components',
+ selectedIcon: Icon(Icons.widgets),
+ ),
+ NavigationDestination(
+ tooltip: '',
+ icon: Icon(Icons.format_paint_outlined),
+ label: 'Color',
+ selectedIcon: Icon(Icons.format_paint),
+ ),
+ NavigationDestination(
+ tooltip: '',
+ icon: Icon(Icons.text_snippet_outlined),
+ label: 'Typography',
+ selectedIcon: Icon(Icons.text_snippet),
+ ),
+ NavigationDestination(
+ tooltip: '',
+ icon: Icon(Icons.invert_colors_on_outlined),
+ label: 'Elevation',
+ selectedIcon: Icon(Icons.opacity),
+ )
+];
+
+const List<Widget> exampleBarDestinations = <Widget>[
+ NavigationDestination(
+ tooltip: '',
+ icon: Icon(Icons.explore_outlined),
+ label: 'Explore',
+ selectedIcon: Icon(Icons.explore),
+ ),
+ NavigationDestination(
+ tooltip: '',
+ icon: Icon(Icons.pets_outlined),
+ label: 'Pets',
+ selectedIcon: Icon(Icons.pets),
+ ),
+ NavigationDestination(
+ tooltip: '',
+ icon: Icon(Icons.account_box_outlined),
+ label: 'Account',
+ selectedIcon: Icon(Icons.account_box),
+ )
+];
+
+List<Widget> barWithBadgeDestinations = <Widget>[
+ NavigationDestination(
+ tooltip: '',
+ icon: Badge.count(count: 1000, child: const Icon(Icons.mail_outlined)),
+ label: 'Mail',
+ selectedIcon: Badge.count(count: 1000, child: const Icon(Icons.mail)),
+ ),
+ const NavigationDestination(
+ tooltip: '',
+ icon: Badge(label: Text('10'), child: Icon(Icons.chat_bubble_outline)),
+ label: 'Chat',
+ selectedIcon: Badge(label: Text('10'), child: Icon(Icons.chat_bubble)),
+ ),
+ const NavigationDestination(
+ tooltip: '',
+ icon: Badge(child: Icon(Icons.group_outlined)),
+ label: 'Rooms',
+ selectedIcon: Badge(child: Icon(Icons.group_rounded)),
+ ),
+ NavigationDestination(
+ tooltip: '',
+ icon: Badge.count(count: 3, child: const Icon(Icons.videocam_outlined)),
+ label: 'Meet',
+ selectedIcon: Badge.count(count: 3, child: const Icon(Icons.videocam)),
+ )
+];
+
+class NavigationBars extends StatefulWidget {
+ const NavigationBars({
+ super.key,
+ this.onSelectItem,
+ required this.selectedIndex,
+ required this.isExampleBar,
+ this.isBadgeExample = false,
+ });
+
+ final void Function(int)? onSelectItem;
+ final int selectedIndex;
+ final bool isExampleBar;
+ final bool isBadgeExample;
+
+ @override
+ State<NavigationBars> createState() => _NavigationBarsState();
+}
+
+class _NavigationBarsState extends State<NavigationBars> {
+ late int selectedIndex;
+
+ @override
+ void initState() {
+ super.initState();
+ selectedIndex = widget.selectedIndex;
+ }
+
+ @override
+ void didUpdateWidget(covariant NavigationBars oldWidget) {
+ super.didUpdateWidget(oldWidget);
+ if (widget.selectedIndex != oldWidget.selectedIndex) {
+ selectedIndex = widget.selectedIndex;
+ }
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ // App NavigationBar should get first focus.
+ Widget navigationBar = Focus(
+ autofocus: !(widget.isExampleBar || widget.isBadgeExample),
+ child: NavigationBar(
+ selectedIndex: selectedIndex,
+ onDestinationSelected: (int index) {
+ setState(() {
+ selectedIndex = index;
+ });
+ if (!widget.isExampleBar) {
+ widget.onSelectItem!(index);
+ }
+ },
+ destinations: widget.isExampleBar && widget.isBadgeExample
+ ? barWithBadgeDestinations
+ : widget.isExampleBar
+ ? exampleBarDestinations
+ : appBarDestinations,
+ ),
+ );
+
+ if (widget.isExampleBar && widget.isBadgeExample) {
+ navigationBar = ComponentDecoration(
+ label: 'Badges',
+ tooltipMessage: 'Use Badge or Badge.count',
+ child: navigationBar);
+ } else if (widget.isExampleBar) {
+ navigationBar = ComponentDecoration(
+ label: 'Navigation bar',
+ tooltipMessage: 'Use NavigationBar',
+ child: navigationBar);
+ }
+
+ return navigationBar;
+ }
+}
+
+class IconToggleButtons extends StatefulWidget {
+ const IconToggleButtons({super.key});
+
+ @override
+ State<IconToggleButtons> createState() => _IconToggleButtonsState();
+}
+
+class _IconToggleButtonsState extends State<IconToggleButtons> {
+ @override
+ Widget build(BuildContext context) {
+ return const ComponentDecoration(
+ label: 'Icon buttons',
+ tooltipMessage: 'Use IconButton',
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceAround,
+ children: <Widget>[
+ Column(
+ // Standard IconButton
+ children: <Widget>[
+ IconToggleButton(
+ isEnabled: true,
+ tooltip: 'Standard',
+ ),
+ colDivider,
+ IconToggleButton(
+ isEnabled: false,
+ tooltip: 'Standard (disabled)',
+ ),
+ ],
+ ),
+ Column(
+ children: <Widget>[
+ // Filled IconButton
+ IconToggleButton(
+ isEnabled: true,
+ tooltip: 'Filled',
+ getDefaultStyle: enabledFilledButtonStyle,
+ ),
+ colDivider,
+ IconToggleButton(
+ isEnabled: false,
+ tooltip: 'Filled (disabled)',
+ getDefaultStyle: disabledFilledButtonStyle,
+ ),
+ ],
+ ),
+ Column(
+ children: <Widget>[
+ // Filled Tonal IconButton
+ IconToggleButton(
+ isEnabled: true,
+ tooltip: 'Filled tonal',
+ getDefaultStyle: enabledFilledTonalButtonStyle,
+ ),
+ colDivider,
+ IconToggleButton(
+ isEnabled: false,
+ tooltip: 'Filled tonal (disabled)',
+ getDefaultStyle: disabledFilledTonalButtonStyle,
+ ),
+ ],
+ ),
+ Column(
+ children: <Widget>[
+ // Outlined IconButton
+ IconToggleButton(
+ isEnabled: true,
+ tooltip: 'Outlined',
+ getDefaultStyle: enabledOutlinedButtonStyle,
+ ),
+ colDivider,
+ IconToggleButton(
+ isEnabled: false,
+ tooltip: 'Outlined (disabled)',
+ getDefaultStyle: disabledOutlinedButtonStyle,
+ ),
+ ],
+ ),
+ ],
+ ),
+ );
+ }
+}
+
+class IconToggleButton extends StatefulWidget {
+ const IconToggleButton({
+ required this.isEnabled,
+ required this.tooltip,
+ this.getDefaultStyle,
+ super.key,
+ });
+
+ final bool isEnabled;
+ final String tooltip;
+ final ButtonStyle? Function(bool, ColorScheme)? getDefaultStyle;
+
+ @override
+ State<IconToggleButton> createState() => _IconToggleButtonState();
+}
+
+class _IconToggleButtonState extends State<IconToggleButton> {
+ bool selected = false;
+
+ @override
+ Widget build(BuildContext context) {
+ final ColorScheme colors = Theme.of(context).colorScheme;
+ final VoidCallback? onPressed = widget.isEnabled
+ ? () {
+ setState(() {
+ selected = !selected;
+ });
+ }
+ : null;
+ final ButtonStyle? style = widget.getDefaultStyle?.call(selected, colors);
+
+ return IconButton(
+ visualDensity: VisualDensity.standard,
+ isSelected: selected,
+ tooltip: widget.tooltip,
+ icon: const Icon(Icons.settings_outlined),
+ selectedIcon: const Icon(Icons.settings),
+ onPressed: onPressed,
+ style: style,
+ );
+ }
+}
+
+ButtonStyle enabledFilledButtonStyle(bool selected, ColorScheme colors) {
+ return IconButton.styleFrom(
+ foregroundColor: selected ? colors.onPrimary : colors.primary,
+ backgroundColor: selected ? colors.primary : colors.surfaceVariant,
+ disabledForegroundColor: colors.onSurface.withOpacity(0.38),
+ disabledBackgroundColor: colors.onSurface.withOpacity(0.12),
+ hoverColor: selected
+ ? colors.onPrimary.withOpacity(0.08)
+ : colors.primary.withOpacity(0.08),
+ focusColor: selected
+ ? colors.onPrimary.withOpacity(0.12)
+ : colors.primary.withOpacity(0.12),
+ highlightColor: selected
+ ? colors.onPrimary.withOpacity(0.12)
+ : colors.primary.withOpacity(0.12),
+ );
+}
+
+ButtonStyle disabledFilledButtonStyle(bool selected, ColorScheme colors) {
+ return IconButton.styleFrom(
+ disabledForegroundColor: colors.onSurface.withOpacity(0.38),
+ disabledBackgroundColor: colors.onSurface.withOpacity(0.12),
+ );
+}
+
+ButtonStyle enabledFilledTonalButtonStyle(bool selected, ColorScheme colors) {
+ return IconButton.styleFrom(
+ foregroundColor:
+ selected ? colors.onSecondaryContainer : colors.onSurfaceVariant,
+ backgroundColor:
+ selected ? colors.secondaryContainer : colors.surfaceVariant,
+ hoverColor: selected
+ ? colors.onSecondaryContainer.withOpacity(0.08)
+ : colors.onSurfaceVariant.withOpacity(0.08),
+ focusColor: selected
+ ? colors.onSecondaryContainer.withOpacity(0.12)
+ : colors.onSurfaceVariant.withOpacity(0.12),
+ highlightColor: selected
+ ? colors.onSecondaryContainer.withOpacity(0.12)
+ : colors.onSurfaceVariant.withOpacity(0.12),
+ );
+}
+
+ButtonStyle disabledFilledTonalButtonStyle(bool selected, ColorScheme colors) {
+ return IconButton.styleFrom(
+ disabledForegroundColor: colors.onSurface.withOpacity(0.38),
+ disabledBackgroundColor: colors.onSurface.withOpacity(0.12),
+ );
+}
+
+ButtonStyle enabledOutlinedButtonStyle(bool selected, ColorScheme colors) {
+ return IconButton.styleFrom(
+ backgroundColor: selected ? colors.inverseSurface : null,
+ hoverColor: selected
+ ? colors.onInverseSurface.withOpacity(0.08)
+ : colors.onSurfaceVariant.withOpacity(0.08),
+ focusColor: selected
+ ? colors.onInverseSurface.withOpacity(0.12)
+ : colors.onSurfaceVariant.withOpacity(0.12),
+ highlightColor: selected
+ ? colors.onInverseSurface.withOpacity(0.12)
+ : colors.onSurface.withOpacity(0.12),
+ side: BorderSide(color: colors.outline),
+ ).copyWith(
+ foregroundColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
+ if (states.contains(MaterialState.selected)) {
+ return colors.onInverseSurface;
+ }
+ if (states.contains(MaterialState.pressed)) {
+ return colors.onSurface;
+ }
+ return null;
+ }),
+ );
+}
+
+ButtonStyle disabledOutlinedButtonStyle(bool selected, ColorScheme colors) {
+ return IconButton.styleFrom(
+ disabledForegroundColor: colors.onSurface.withOpacity(0.38),
+ disabledBackgroundColor:
+ selected ? colors.onSurface.withOpacity(0.12) : null,
+ side: selected ? null : BorderSide(color: colors.outline.withOpacity(0.12)),
+ );
+}
+
+class Chips extends StatefulWidget {
+ const Chips({super.key});
+
+ @override
+ State<Chips> createState() => _ChipsState();
+}
+
+class _ChipsState extends State<Chips> {
+ bool isFiltered = true;
+
+ @override
+ Widget build(BuildContext context) {
+ return ComponentDecoration(
+ label: 'Chips',
+ tooltipMessage:
+ 'Use ActionChip, FilterChip, or InputChip. \nActionChip can also be used for suggestion chip',
+ child: Column(
+ children: <Widget>[
+ Wrap(
+ spacing: smallSpacing,
+ runSpacing: smallSpacing,
+ children: <Widget>[
+ ActionChip(
+ label: const Text('Assist'),
+ avatar: const Icon(Icons.event),
+ onPressed: () {},
+ ),
+ FilterChip(
+ label: const Text('Filter'),
+ selected: isFiltered,
+ onSelected: (bool selected) {
+ setState(() => isFiltered = selected);
+ },
+ ),
+ InputChip(
+ label: const Text('Input'),
+ onPressed: () {},
+ onDeleted: () {},
+ ),
+ ActionChip(
+ label: const Text('Suggestion'),
+ onPressed: () {},
+ ),
+ ],
+ ),
+ colDivider,
+ Wrap(
+ spacing: smallSpacing,
+ runSpacing: smallSpacing,
+ children: <Widget>[
+ const ActionChip(
+ label: Text('Assist'),
+ avatar: Icon(Icons.event),
+ ),
+ FilterChip(
+ label: const Text('Filter'),
+ selected: isFiltered,
+ onSelected: null,
+ ),
+ InputChip(
+ label: const Text('Input'),
+ onDeleted: () {},
+ isEnabled: false,
+ ),
+ const ActionChip(
+ label: Text('Suggestion'),
+ ),
+ ],
+ ),
+ ],
+ ),
+ );
+ }
+}
+
+class SegmentedButtons extends StatelessWidget {
+ const SegmentedButtons({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return const ComponentDecoration(
+ label: 'Segmented buttons',
+ tooltipMessage: 'Use SegmentedButton<T>',
+ child: Column(
+ children: <Widget>[
+ SingleChoice(),
+ colDivider,
+ MultipleChoice(),
+ ],
+ ),
+ );
+ }
+}
+
+enum Calendar { day, week, month, year }
+
+class SingleChoice extends StatefulWidget {
+ const SingleChoice({super.key});
+
+ @override
+ State<SingleChoice> createState() => _SingleChoiceState();
+}
+
+class _SingleChoiceState extends State<SingleChoice> {
+ Calendar calendarView = Calendar.day;
+
+ @override
+ Widget build(BuildContext context) {
+ return SegmentedButton<Calendar>(
+ segments: const <ButtonSegment<Calendar>>[
+ ButtonSegment<Calendar>(
+ value: Calendar.day,
+ label: Text('Day'),
+ icon: Icon(Icons.calendar_view_day)),
+ ButtonSegment<Calendar>(
+ value: Calendar.week,
+ label: Text('Week'),
+ icon: Icon(Icons.calendar_view_week)),
+ ButtonSegment<Calendar>(
+ value: Calendar.month,
+ label: Text('Month'),
+ icon: Icon(Icons.calendar_view_month)),
+ ButtonSegment<Calendar>(
+ value: Calendar.year,
+ label: Text('Year'),
+ icon: Icon(Icons.calendar_today)),
+ ],
+ selected: <Calendar>{calendarView},
+ onSelectionChanged: (Set<Calendar> newSelection) {
+ setState(() {
+ // By default there is only a single segment that can be
+ // selected at one time, so its value is always the first
+ // item in the selected set.
+ calendarView = newSelection.first;
+ });
+ },
+ );
+ }
+}
+
+enum Sizes { extraSmall, small, medium, large, extraLarge }
+
+class MultipleChoice extends StatefulWidget {
+ const MultipleChoice({super.key});
+
+ @override
+ State<MultipleChoice> createState() => _MultipleChoiceState();
+}
+
+class _MultipleChoiceState extends State<MultipleChoice> {
+ Set<Sizes> selection = <Sizes>{Sizes.large, Sizes.extraLarge};
+
+ @override
+ Widget build(BuildContext context) {
+ return SegmentedButton<Sizes>(
+ segments: const <ButtonSegment<Sizes>>[
+ ButtonSegment<Sizes>(value: Sizes.extraSmall, label: Text('XS')),
+ ButtonSegment<Sizes>(value: Sizes.small, label: Text('S')),
+ ButtonSegment<Sizes>(value: Sizes.medium, label: Text('M')),
+ ButtonSegment<Sizes>(
+ value: Sizes.large,
+ label: Text('L'),
+ ),
+ ButtonSegment<Sizes>(value: Sizes.extraLarge, label: Text('XL')),
+ ],
+ selected: selection,
+ onSelectionChanged: (Set<Sizes> newSelection) {
+ setState(() {
+ selection = newSelection;
+ });
+ },
+ multiSelectionEnabled: true,
+ );
+ }
+}
+
+class SnackBarSection extends StatelessWidget {
+ const SnackBarSection({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return ComponentDecoration(
+ label: 'Snackbar',
+ tooltipMessage:
+ 'Use ScaffoldMessenger.of(context).showSnackBar with SnackBar',
+ child: TextButton(
+ onPressed: () {
+ final SnackBar snackBar = SnackBar(
+ behavior: SnackBarBehavior.floating,
+ width: 400.0,
+ content: const Text('This is a snackbar'),
+ action: SnackBarAction(
+ label: 'Close',
+ onPressed: () {},
+ ),
+ );
+
+ ScaffoldMessenger.of(context).hideCurrentSnackBar();
+ ScaffoldMessenger.of(context).showSnackBar(snackBar);
+ },
+ child: const Text(
+ 'Show snackbar',
+ style: TextStyle(fontWeight: FontWeight.bold),
+ ),
+ ),
+ );
+ }
+}
+
+class BottomSheetSection extends StatefulWidget {
+ const BottomSheetSection({super.key});
+
+ @override
+ State<BottomSheetSection> createState() => _BottomSheetSectionState();
+}
+
+class _BottomSheetSectionState extends State<BottomSheetSection> {
+ bool isNonModalBottomSheetOpen = false;
+ PersistentBottomSheetController<void>? _nonModalBottomSheetController;
+
+ @override
+ Widget build(BuildContext context) {
+ List<Widget> buttonList = <Widget>[
+ IconButton(onPressed: () {}, icon: const Icon(Icons.share_outlined)),
+ IconButton(onPressed: () {}, icon: const Icon(Icons.add)),
+ IconButton(onPressed: () {}, icon: const Icon(Icons.delete_outline)),
+ IconButton(onPressed: () {}, icon: const Icon(Icons.archive_outlined)),
+ IconButton(onPressed: () {}, icon: const Icon(Icons.settings_outlined)),
+ IconButton(onPressed: () {}, icon: const Icon(Icons.favorite_border)),
+ ];
+ const List<Text> labelList = <Text>[
+ Text('Share'),
+ Text('Add to'),
+ Text('Trash'),
+ Text('Archive'),
+ Text('Settings'),
+ Text('Favorite')
+ ];
+
+ buttonList = List<Widget>.generate(
+ buttonList.length,
+ (int index) => Padding(
+ padding: const EdgeInsets.fromLTRB(20.0, 30.0, 20.0, 20.0),
+ child: Column(
+ children: <Widget>[
+ buttonList[index],
+ labelList[index],
+ ],
+ ),
+ ));
+
+ return ComponentDecoration(
+ label: 'Bottom sheet',
+ tooltipMessage: 'Use showModalBottomSheet<T> or showBottomSheet<T>',
+ child: Wrap(
+ alignment: WrapAlignment.spaceEvenly,
+ children: <Widget>[
+ TextButton(
+ child: const Text(
+ 'Show modal bottom sheet',
+ style: TextStyle(fontWeight: FontWeight.bold),
+ ),
+ onPressed: () {
+ showModalBottomSheet<void>(
+ context: context,
+ constraints: const BoxConstraints(maxWidth: 640),
+ builder: (BuildContext context) {
+ return SizedBox(
+ height: 150,
+ child: Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 32.0),
+ child: ListView(
+ shrinkWrap: true,
+ scrollDirection: Axis.horizontal,
+ children: buttonList,
+ ),
+ ),
+ );
+ },
+ );
+ },
+ ),
+ TextButton(
+ child: Text(
+ isNonModalBottomSheetOpen
+ ? 'Hide bottom sheet'
+ : 'Show bottom sheet',
+ style: const TextStyle(fontWeight: FontWeight.bold),
+ ),
+ onPressed: () {
+ if (isNonModalBottomSheetOpen) {
+ _nonModalBottomSheetController?.close();
+ setState(() {
+ isNonModalBottomSheetOpen = false;
+ });
+ return;
+ } else {
+ setState(() {
+ isNonModalBottomSheetOpen = true;
+ });
+ }
+
+ _nonModalBottomSheetController = showBottomSheet<void>(
+ elevation: 8.0,
+ context: context,
+ constraints: const BoxConstraints(maxWidth: 640),
+ builder: (BuildContext context) {
+ return SizedBox(
+ height: 150,
+ child: Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 32.0),
+ child: ListView(
+ shrinkWrap: true,
+ scrollDirection: Axis.horizontal,
+ children: buttonList,
+ ),
+ ),
+ );
+ },
+ );
+ },
+ ),
+ ],
+ ),
+ );
+ }
+}
+
+class BottomAppBars extends StatelessWidget {
+ const BottomAppBars({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return ComponentDecoration(
+ label: 'Bottom app bar',
+ tooltipMessage: 'Use BottomAppBar',
+ child: Column(
+ children: <Widget>[
+ SizedBox(
+ height: 80,
+ child: Scaffold(
+ floatingActionButton: FloatingActionButton(
+ onPressed: () {},
+ elevation: 0.0,
+ child: const Icon(Icons.add),
+ ),
+ floatingActionButtonLocation:
+ FloatingActionButtonLocation.endContained,
+ bottomNavigationBar: BottomAppBar(
+ child: Row(
+ children: <Widget>[
+ const IconButtonAnchorExample(),
+ IconButton(
+ tooltip: 'Search',
+ icon: const Icon(Icons.search),
+ onPressed: () {},
+ ),
+ IconButton(
+ tooltip: 'Favorite',
+ icon: const Icon(Icons.favorite),
+ onPressed: () {},
+ ),
+ ],
+ ),
+ ),
+ ),
+ ),
+ ],
+ ),
+ );
+ }
+}
+
+class IconButtonAnchorExample extends StatelessWidget {
+ const IconButtonAnchorExample({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return MenuAnchor(
+ builder: (BuildContext context, MenuController controller, Widget? child) {
+ return IconButton(
+ onPressed: () {
+ if (controller.isOpen) {
+ controller.close();
+ } else {
+ controller.open();
+ }
+ },
+ icon: const Icon(Icons.more_vert),
+ );
+ },
+ menuChildren: <Widget>[
+ MenuItemButton(
+ child: const Text('Menu 1'),
+ onPressed: () {},
+ ),
+ MenuItemButton(
+ child: const Text('Menu 2'),
+ onPressed: () {},
+ ),
+ SubmenuButton(
+ menuChildren: <Widget>[
+ MenuItemButton(
+ onPressed: () {},
+ child: const Text('Menu 3.1'),
+ ),
+ MenuItemButton(
+ onPressed: () {},
+ child: const Text('Menu 3.2'),
+ ),
+ MenuItemButton(
+ onPressed: () {},
+ child: const Text('Menu 3.3'),
+ ),
+ ],
+ child: const Text('Menu 3'),
+ ),
+ ],
+ );
+ }
+}
+
+class ButtonAnchorExample extends StatelessWidget {
+ const ButtonAnchorExample({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return MenuAnchor(
+ builder: (BuildContext context, MenuController controller, Widget? child) {
+ return FilledButton.tonal(
+ onPressed: () {
+ if (controller.isOpen) {
+ controller.close();
+ } else {
+ controller.open();
+ }
+ },
+ child: const Text('Show menu'),
+ );
+ },
+ menuChildren: <Widget>[
+ MenuItemButton(
+ leadingIcon: const Icon(Icons.people_alt_outlined),
+ child: const Text('Item 1'),
+ onPressed: () {},
+ ),
+ MenuItemButton(
+ leadingIcon: const Icon(Icons.remove_red_eye_outlined),
+ child: const Text('Item 2'),
+ onPressed: () {},
+ ),
+ MenuItemButton(
+ leadingIcon: const Icon(Icons.refresh),
+ onPressed: () {},
+ child: const Text('Item 3'),
+ ),
+ ],
+ );
+ }
+}
+
+class NavigationDrawers extends StatelessWidget {
+ const NavigationDrawers({super.key, required this.scaffoldKey});
+ final GlobalKey<ScaffoldState> scaffoldKey;
+
+ @override
+ Widget build(BuildContext context) {
+ return ComponentDecoration(
+ label: 'Navigation drawer',
+ tooltipMessage:
+ 'Use NavigationDrawer. For modal navigation drawers, see Scaffold.endDrawer',
+ child: Column(
+ children: <Widget>[
+ const SizedBox(height: 520, child: NavigationDrawerSection()),
+ colDivider,
+ colDivider,
+ TextButton(
+ child: const Text('Show modal navigation drawer',
+ style: TextStyle(fontWeight: FontWeight.bold)),
+ onPressed: () {
+ scaffoldKey.currentState!.openEndDrawer();
+ },
+ ),
+ ],
+ ),
+ );
+ }
+}
+
+class NavigationDrawerSection extends StatefulWidget {
+ const NavigationDrawerSection({super.key});
+
+ @override
+ State<NavigationDrawerSection> createState() =>
+ _NavigationDrawerSectionState();
+}
+
+class _NavigationDrawerSectionState extends State<NavigationDrawerSection> {
+ int navDrawerIndex = 0;
+
+ @override
+ Widget build(BuildContext context) {
+ return NavigationDrawer(
+ onDestinationSelected: (int selectedIndex) {
+ setState(() {
+ navDrawerIndex = selectedIndex;
+ });
+ },
+ selectedIndex: navDrawerIndex,
+ children: <Widget>[
+ Padding(
+ padding: const EdgeInsets.fromLTRB(28, 16, 16, 10),
+ child: Text(
+ 'Mail',
+ style: Theme.of(context).textTheme.titleSmall,
+ ),
+ ),
+ ...destinations.map((ExampleDestination destination) {
+ return NavigationDrawerDestination(
+ label: Text(destination.label),
+ icon: destination.icon,
+ selectedIcon: destination.selectedIcon,
+ );
+ }),
+ const Divider(indent: 28, endIndent: 28),
+ Padding(
+ padding: const EdgeInsets.fromLTRB(28, 16, 16, 10),
+ child: Text(
+ 'Labels',
+ style: Theme.of(context).textTheme.titleSmall,
+ ),
+ ),
+ ...labelDestinations.map((ExampleDestination destination) {
+ return NavigationDrawerDestination(
+ label: Text(destination.label),
+ icon: destination.icon,
+ selectedIcon: destination.selectedIcon,
+ );
+ }),
+ ],
+ );
+ }
+}
+
+class ExampleDestination {
+ const ExampleDestination(this.label, this.icon, this.selectedIcon);
+
+ final String label;
+ final Widget icon;
+ final Widget selectedIcon;
+}
+
+const List<ExampleDestination> destinations = <ExampleDestination>[
+ ExampleDestination('Inbox', Icon(Icons.inbox_outlined), Icon(Icons.inbox)),
+ ExampleDestination('Outbox', Icon(Icons.send_outlined), Icon(Icons.send)),
+ ExampleDestination(
+ 'Favorites', Icon(Icons.favorite_outline), Icon(Icons.favorite)),
+ ExampleDestination('Trash', Icon(Icons.delete_outline), Icon(Icons.delete)),
+];
+
+const List<ExampleDestination> labelDestinations = <ExampleDestination>[
+ ExampleDestination(
+ 'Family', Icon(Icons.bookmark_border), Icon(Icons.bookmark)),
+ ExampleDestination(
+ 'School', Icon(Icons.bookmark_border), Icon(Icons.bookmark)),
+ ExampleDestination('Work', Icon(Icons.bookmark_border), Icon(Icons.bookmark)),
+];
+
+class NavigationRails extends StatelessWidget {
+ const NavigationRails({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return const ComponentDecoration(
+ label: 'Navigation rail',
+ tooltipMessage: 'Use NavigationRail',
+ child: IntrinsicWidth(
+ child: SizedBox(height: 420, child: NavigationRailSection())),
+ );
+ }
+}
+
+class NavigationRailSection extends StatefulWidget {
+ const NavigationRailSection({super.key});
+
+ @override
+ State<NavigationRailSection> createState() => _NavigationRailSectionState();
+}
+
+class _NavigationRailSectionState extends State<NavigationRailSection> {
+ int navRailIndex = 0;
+
+ @override
+ Widget build(BuildContext context) {
+ return NavigationRail(
+ onDestinationSelected: (int selectedIndex) {
+ setState(() {
+ navRailIndex = selectedIndex;
+ });
+ },
+ elevation: 4,
+ leading: FloatingActionButton(
+ child: const Icon(Icons.create), onPressed: () {}),
+ groupAlignment: 0.0,
+ selectedIndex: navRailIndex,
+ labelType: NavigationRailLabelType.selected,
+ destinations: <NavigationRailDestination>[
+ ...destinations.map((ExampleDestination destination) {
+ return NavigationRailDestination(
+ label: Text(destination.label),
+ icon: destination.icon,
+ selectedIcon: destination.selectedIcon,
+ );
+ }),
+ ],
+ );
+ }
+}
+
+class Tabs extends StatefulWidget {
+ const Tabs({super.key});
+
+ @override
+ State<Tabs> createState() => _TabsState();
+}
+
+class _TabsState extends State<Tabs> with TickerProviderStateMixin {
+ late TabController _tabController;
+
+ @override
+ void initState() {
+ super.initState();
+ _tabController = TabController(length: 3, vsync: this);
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return ComponentDecoration(
+ label: 'Tabs',
+ tooltipMessage: 'Use TabBar',
+ child: SizedBox(
+ height: 80,
+ child: Scaffold(
+ appBar: AppBar(
+ bottom: TabBar(
+ controller: _tabController,
+ tabs: const <Widget>[
+ Tab(
+ icon: Icon(Icons.videocam_outlined),
+ text: 'Video',
+ iconMargin: EdgeInsets.zero,
+ ),
+ Tab(
+ icon: Icon(Icons.photo_outlined),
+ text: 'Photos',
+ iconMargin: EdgeInsets.zero,
+ ),
+ Tab(
+ icon: Icon(Icons.audiotrack_sharp),
+ text: 'Audio',
+ iconMargin: EdgeInsets.zero,
+ ),
+ ],
+ ),
+ ),
+ ),
+ ),
+ );
+ }
+}
+
+class TopAppBars extends StatelessWidget {
+ const TopAppBars({super.key});
+
+ static final List<IconButton> actions = <IconButton>[
+ IconButton(icon: const Icon(Icons.attach_file), onPressed: () {}),
+ IconButton(icon: const Icon(Icons.event), onPressed: () {}),
+ IconButton(icon: const Icon(Icons.more_vert), onPressed: () {}),
+ ];
+
+ @override
+ Widget build(BuildContext context) {
+ return ComponentDecoration(
+ label: 'Top app bars',
+ tooltipMessage:
+ 'Use AppBar, SliverAppBar, SliverAppBar.medium, or SliverAppBar.large',
+ child: Column(
+ children: <Widget>[
+ AppBar(
+ title: const Text('Center-aligned'),
+ leading: const BackButton(),
+ actions: <Widget>[
+ IconButton(
+ iconSize: 32,
+ icon: const Icon(Icons.account_circle_outlined),
+ onPressed: () {},
+ ),
+ ],
+ centerTitle: true,
+ ),
+ colDivider,
+ AppBar(
+ title: const Text('Small'),
+ leading: const BackButton(),
+ actions: actions,
+ centerTitle: false,
+ ),
+ colDivider,
+ SizedBox(
+ height: 100,
+ child: CustomScrollView(
+ slivers: <Widget>[
+ SliverAppBar.medium(
+ title: const Text('Medium'),
+ leading: const BackButton(),
+ actions: actions,
+ ),
+ const SliverFillRemaining(),
+ ],
+ ),
+ ),
+ colDivider,
+ SizedBox(
+ height: 130,
+ child: CustomScrollView(
+ slivers: <Widget>[
+ SliverAppBar.large(
+ title: const Text('Large'),
+ leading: const BackButton(),
+ actions: actions,
+ ),
+ const SliverFillRemaining(),
+ ],
+ ),
+ ),
+ ],
+ ),
+ );
+ }
+}
+
+class Menus extends StatefulWidget {
+ const Menus({super.key});
+
+ @override
+ State<Menus> createState() => _MenusState();
+}
+
+class _MenusState extends State<Menus> {
+ final TextEditingController colorController = TextEditingController();
+ final TextEditingController iconController = TextEditingController();
+ IconLabel? selectedIcon = IconLabel.smile;
+ ColorLabel? selectedColor;
+
+ @override
+ Widget build(BuildContext context) {
+ final List<DropdownMenuEntry<ColorLabel>> colorEntries =
+ <DropdownMenuEntry<ColorLabel>>[];
+ for (final ColorLabel color in ColorLabel.values) {
+ colorEntries.add(DropdownMenuEntry<ColorLabel>(
+ value: color, label: color.label, enabled: color.label != 'Grey'));
+ }
+
+ final List<DropdownMenuEntry<IconLabel>> iconEntries =
+ <DropdownMenuEntry<IconLabel>>[];
+ for (final IconLabel icon in IconLabel.values) {
+ iconEntries
+ .add(DropdownMenuEntry<IconLabel>(value: icon, label: icon.label));
+ }
+
+ return ComponentDecoration(
+ label: 'Menus',
+ tooltipMessage: 'Use MenuAnchor or DropdownMenu<T>',
+ child: Column(
+ children: <Widget>[
+ const Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: <Widget>[
+ ButtonAnchorExample(),
+ rowDivider,
+ IconButtonAnchorExample(),
+ ],
+ ),
+ colDivider,
+ Wrap(
+ alignment: WrapAlignment.spaceAround,
+ runAlignment: WrapAlignment.center,
+ crossAxisAlignment: WrapCrossAlignment.center,
+ spacing: smallSpacing,
+ runSpacing: smallSpacing,
+ children: <Widget>[
+ DropdownMenu<ColorLabel>(
+ controller: colorController,
+ label: const Text('Color'),
+ enableFilter: true,
+ dropdownMenuEntries: colorEntries,
+ inputDecorationTheme: const InputDecorationTheme(filled: true),
+ onSelected: (ColorLabel? color) {
+ setState(() {
+ selectedColor = color;
+ });
+ },
+ ),
+ DropdownMenu<IconLabel>(
+ initialSelection: IconLabel.smile,
+ controller: iconController,
+ leadingIcon: const Icon(Icons.search),
+ label: const Text('Icon'),
+ dropdownMenuEntries: iconEntries,
+ onSelected: (IconLabel? icon) {
+ setState(() {
+ selectedIcon = icon;
+ });
+ },
+ ),
+ Icon(
+ selectedIcon?.icon,
+ color: selectedColor?.color ?? Colors.grey.withOpacity(0.5),
+ )
+ ],
+ ),
+ ],
+ ),
+ );
+ }
+}
+
+enum ColorLabel {
+ blue('Blue', Colors.blue),
+ pink('Pink', Colors.pink),
+ green('Green', Colors.green),
+ yellow('Yellow', Colors.yellow),
+ grey('Grey', Colors.grey);
+
+ const ColorLabel(this.label, this.color);
+ final String label;
+ final Color color;
+}
+
+enum IconLabel {
+ smile('Smile', Icons.sentiment_satisfied_outlined),
+ cloud(
+ 'Cloud',
+ Icons.cloud_outlined,
+ ),
+ brush('Brush', Icons.brush_outlined),
+ heart('Heart', Icons.favorite);
+
+ const IconLabel(this.label, this.icon);
+ final String label;
+ final IconData icon;
+}
+
+class Sliders extends StatefulWidget {
+ const Sliders({super.key});
+
+ @override
+ State<Sliders> createState() => _SlidersState();
+}
+
+class _SlidersState extends State<Sliders> {
+ double sliderValue0 = 30.0;
+ double sliderValue1 = 20.0;
+
+ @override
+ Widget build(BuildContext context) {
+ return ComponentDecoration(
+ label: 'Sliders',
+ tooltipMessage: 'Use Slider or RangeSlider',
+ child: Column(
+ children: <Widget>[
+ Slider(
+ max: 100,
+ value: sliderValue0,
+ onChanged: (double value) {
+ setState(() {
+ sliderValue0 = value;
+ });
+ },
+ ),
+ const SizedBox(height: 20),
+ Slider(
+ max: 100,
+ divisions: 5,
+ value: sliderValue1,
+ label: sliderValue1.round().toString(),
+ onChanged: (double value) {
+ setState(() {
+ sliderValue1 = value;
+ });
+ },
+ ),
+ ],
+ ));
+ }
+}
+
+class ComponentDecoration extends StatefulWidget {
+ const ComponentDecoration({
+ super.key,
+ required this.label,
+ required this.child,
+ this.tooltipMessage = '',
+ });
+
+ final String label;
+ final Widget child;
+ final String? tooltipMessage;
+
+ @override
+ State<ComponentDecoration> createState() => _ComponentDecorationState();
+}
+
+class _ComponentDecorationState extends State<ComponentDecoration> {
+ final FocusNode focusNode = FocusNode();
+
+ @override
+ Widget build(BuildContext context) {
+ return RepaintBoundary(
+ child: Padding(
+ padding: const EdgeInsets.symmetric(vertical: smallSpacing),
+ child: Column(
+ children: <Widget>[
+ Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: <Widget>[
+ Text(widget.label,
+ style: Theme.of(context).textTheme.titleSmall),
+ Tooltip(
+ message: widget.tooltipMessage,
+ child: const Padding(
+ padding: EdgeInsets.symmetric(horizontal: 5.0),
+ child: Icon(Icons.info_outline, size: 16)),
+ ),
+ ],
+ ),
+ ConstrainedBox(
+ constraints:
+ const BoxConstraints.tightFor(width: widthConstraint),
+ // Tapping within the a component card should request focus
+ // for that component's children.
+ child: Focus(
+ focusNode: focusNode,
+ canRequestFocus: true,
+ child: GestureDetector(
+ onTapDown: (_) {
+ focusNode.requestFocus();
+ },
+ behavior: HitTestBehavior.opaque,
+ child: Card(
+ elevation: 0,
+ shape: RoundedRectangleBorder(
+ side: BorderSide(
+ color: Theme.of(context).colorScheme.outlineVariant,
+ ),
+ borderRadius: const BorderRadius.all(Radius.circular(12)),
+ ),
+ child: Padding(
+ padding: const EdgeInsets.symmetric(
+ horizontal: 5.0, vertical: 20.0),
+ child: Center(
+ child: widget.child,
+ ),
+ ),
+ ),
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+}
+
+class ComponentGroupDecoration extends StatelessWidget {
+ const ComponentGroupDecoration(
+ {super.key, required this.label, required this.children});
+
+ final String label;
+ final List<Widget> children;
+
+ @override
+ Widget build(BuildContext context) {
+ // Fully traverse this component group before moving on
+ return FocusTraversalGroup(
+ child: Card(
+ margin: EdgeInsets.zero,
+ elevation: 0,
+ color: Theme.of(context).colorScheme.surfaceVariant.withOpacity(0.3),
+ child: Padding(
+ padding: const EdgeInsets.symmetric(vertical: 20.0),
+ child: Center(
+ child: Column(
+ children: <Widget>[
+ Text(label, style: Theme.of(context).textTheme.titleLarge),
+ colDivider,
+ ...children
+ ],
+ ),
+ ),
+ ),
+ ),
+ );
+ }
+}
diff --git a/dev/benchmarks/macrobenchmarks/lib/src/web/recorder.dart b/dev/benchmarks/macrobenchmarks/lib/src/web/recorder.dart
index 50e1658..3e867ac 100644
--- a/dev/benchmarks/macrobenchmarks/lib/src/web/recorder.dart
+++ b/dev/benchmarks/macrobenchmarks/lib/src/web/recorder.dart
@@ -426,12 +426,18 @@
_runCompleter!.completeError(error, stackTrace);
}
+ late final _RecordingWidgetsBinding _binding;
+
+ @override
+ @mustCallSuper
+ Future<void> setUpAll() async {
+ _binding = _RecordingWidgetsBinding.ensureInitialized();
+ }
+
@override
Future<Profile> run() async {
_runCompleter = Completer<void>();
final Profile localProfile = profile = Profile(name: name, useCustomWarmUp: useCustomWarmUp);
- final _RecordingWidgetsBinding binding =
- _RecordingWidgetsBinding.ensureInitialized();
final Widget widget = createWidget();
registerEngineBenchmarkValueListener(kProfilePrerollFrame, (num value) {
@@ -449,7 +455,7 @@
);
});
- binding._beginRecording(this, widget);
+ _binding._beginRecording(this, widget);
try {
await _runCompleter!.future;
@@ -508,6 +514,14 @@
}
}
+ late final _RecordingWidgetsBinding _binding;
+
+ @override
+ @mustCallSuper
+ Future<void> setUpAll() async {
+ _binding = _RecordingWidgetsBinding.ensureInitialized();
+ }
+
@override
@mustCallSuper
void frameWillDraw() {
@@ -546,9 +560,7 @@
Future<Profile> run() async {
_runCompleter = Completer<void>();
final Profile localProfile = profile = Profile(name: name);
- final _RecordingWidgetsBinding binding =
- _RecordingWidgetsBinding.ensureInitialized();
- binding._beginRecording(this, _WidgetBuildRecorderHost(this));
+ _binding._beginRecording(this, _WidgetBuildRecorderHost(this));
try {
await _runCompleter!.future;
@@ -948,6 +960,15 @@
}
}
+ /// A convenience wrapper over [addDataPoint] for adding [AggregatedTimedBlock]
+ /// to the profile.
+ ///
+ /// Uses [AggregatedTimedBlock.name] as the name of the data point, and
+ /// [AggregatedTimedBlock.duration] as the duration.
+ void addTimedBlock(AggregatedTimedBlock timedBlock, { required bool reported }) {
+ addDataPoint(timedBlock.name, Duration(microseconds: timedBlock.duration.toInt()), reported: reported);
+ }
+
/// Checks the samples collected so far and sets the appropriate benchmark phase.
///
/// If enough warm-up samples have been collected, stops the warm-up phase and
@@ -1258,7 +1279,7 @@
if (!profile.isWarmingUp) {
// Tell the browser to mark the beginning of the frame.
- web.window.performance.mark('measured_frame_start#$_currentFrameNumber'.toJS);
+ web.window.performance.mark('measured_frame_start#$_currentFrameNumber');
_isMeasuringFrame = true;
}
}
@@ -1280,11 +1301,11 @@
if (_isMeasuringFrame) {
// Tell the browser to mark the end of the frame, and measure the duration.
- web.window.performance.mark('measured_frame_end#$_currentFrameNumber'.toJS);
+ web.window.performance.mark('measured_frame_end#$_currentFrameNumber');
web.window.performance.measure(
- 'measured_frame'.toJS,
+ 'measured_frame',
'measured_frame_start#$_currentFrameNumber'.toJS,
- 'measured_frame_end#$_currentFrameNumber'.toJS,
+ 'measured_frame_end#$_currentFrameNumber',
);
// Increment the current frame number.
@@ -1315,9 +1336,7 @@
if (_engineBenchmarkListeners.isEmpty) {
// The first listener is being registered. Register the global listener.
web.window['_flutter_internal_on_benchmark'.toJS] =
- // Upcast to [Object] to export.
- // ignore: unnecessary_cast
- (_dispatchEngineBenchmarkValue as Object).toJS;
+ _dispatchEngineBenchmarkValue.toJS;
}
_engineBenchmarkListeners[name] = listener;
}
diff --git a/dev/benchmarks/macrobenchmarks/lib/web_benchmarks.dart b/dev/benchmarks/macrobenchmarks/lib/web_benchmarks.dart
index 497ec56..e4e18d5 100644
--- a/dev/benchmarks/macrobenchmarks/lib/web_benchmarks.dart
+++ b/dev/benchmarks/macrobenchmarks/lib/web_benchmarks.dart
@@ -19,6 +19,7 @@
import 'src/web/bench_dynamic_clip_on_static_picture.dart';
import 'src/web/bench_image_decoding.dart';
import 'src/web/bench_material_3.dart';
+import 'src/web/bench_material_3_semantics.dart';
import 'src/web/bench_mouse_region_grid_hover.dart';
import 'src/web/bench_mouse_region_grid_scroll.dart';
import 'src/web/bench_mouse_region_mixed_grid_hover.dart';
@@ -35,6 +36,7 @@
typedef RecorderFactory = Recorder Function();
const bool isCanvasKit = bool.fromEnvironment('FLUTTER_WEB_USE_SKIA');
+const bool isSkwasm = bool.fromEnvironment('FLUTTER_WEB_USE_SKWASM');
/// List of all benchmarks that run in the devicelab.
///
@@ -61,12 +63,18 @@
BenchMouseRegionGridHover.benchmarkName: () => BenchMouseRegionGridHover(),
BenchMouseRegionMixedGridHover.benchmarkName: () => BenchMouseRegionMixedGridHover(),
BenchWrapBoxScroll.benchmarkName: () => BenchWrapBoxScroll(),
- BenchPlatformViewInfiniteScroll.benchmarkName: () => BenchPlatformViewInfiniteScroll.forward(),
- BenchPlatformViewInfiniteScroll.benchmarkNameBackward: () => BenchPlatformViewInfiniteScroll.backward(),
+ if (!isSkwasm) ...<String, RecorderFactory>{
+ // Platform views are not yet supported with Skwasm.
+ // https://github.com/flutter/flutter/issues/126346
+ BenchPlatformViewInfiniteScroll.benchmarkName: () => BenchPlatformViewInfiniteScroll.forward(),
+ BenchPlatformViewInfiniteScroll.benchmarkNameBackward: () => BenchPlatformViewInfiniteScroll.backward(),
+ },
BenchMaterial3Components.benchmarkName: () => BenchMaterial3Components(),
+ BenchMaterial3Semantics.benchmarkName: () => BenchMaterial3Semantics(),
+ BenchMaterial3ScrollSemantics.benchmarkName: () => BenchMaterial3ScrollSemantics(),
- // CanvasKit-only benchmarks
- if (isCanvasKit) ...<String, RecorderFactory>{
+ // Skia-only benchmarks
+ if (isCanvasKit || isSkwasm) ...<String, RecorderFactory>{
BenchTextLayout.canvasKitBenchmarkName: () => BenchTextLayout.canvasKit(),
BenchBuildColorsGrid.canvasKitBenchmarkName: () => BenchBuildColorsGrid.canvasKit(),
BenchTextCachedLayout.canvasKitBenchmarkName: () => BenchTextCachedLayout.canvasKit(),
@@ -78,7 +86,7 @@
},
// HTML-only benchmarks
- if (!isCanvasKit) ...<String, RecorderFactory>{
+ if (!isCanvasKit && !isSkwasm) ...<String, RecorderFactory>{
BenchTextLayout.canvasBenchmarkName: () => BenchTextLayout.canvas(),
BenchTextCachedLayout.canvasBenchmarkName: () => BenchTextCachedLayout.canvas(),
BenchBuildColorsGrid.canvasBenchmarkName: () => BenchBuildColorsGrid.canvas(),
@@ -154,9 +162,9 @@
extension WebHTMLElementExtension on web.HTMLElement {
void appendHtml(String html) {
- final web.HTMLDivElement div = web.document.createElement('div'.toJS) as
+ final web.HTMLDivElement div = web.document.createElement('div') as
web.HTMLDivElement;
- div.innerHTML = html.toJS;
+ div.innerHTML = html;
final web.DocumentFragment fragment = web.document.createDocumentFragment();
fragment.append(div);
web.document.adoptNode(fragment);
@@ -183,10 +191,10 @@
''');
for (final String benchmarkName in benchmarks.keys) {
- final web.Element button = web.document.querySelector('#$benchmarkName'.toJS)!;
- button.addEventListener('click'.toJS, (JSObject _) {
+ final web.Element button = web.document.querySelector('#$benchmarkName')!;
+ button.addEventListener('click', (JSObject _) {
final web.Element? manualPanel =
- web.document.querySelector('#manual-panel'.toJS);
+ web.document.querySelector('#manual-panel');
manualPanel?.remove();
_runBenchmark(benchmarkName);
}.toJS);
@@ -196,7 +204,7 @@
/// Visualizes results on the Web page for manual inspection.
void _printResultsToScreen(Profile profile) {
web.document.body!.remove();
- web.document.body = web.document.createElement('body'.toJS) as web.HTMLBodyElement;
+ web.document.body = web.document.createElement('body') as web.HTMLBodyElement;
web.document.body!.appendHtml('<h2>${profile.name}</h2>');
profile.scoreData.forEach((String scoreKey, Timeseries timeseries) {
@@ -210,15 +218,15 @@
class TimeseriesVisualization {
TimeseriesVisualization(this._timeseries) {
_stats = _timeseries.computeStats();
- _canvas = web.document.createElement('canvas'.toJS) as web.HTMLCanvasElement;
- _screenWidth = web.window.screen.width.toDart.toInt();
- _canvas.width = _screenWidth.toJS;
- _canvas.height = (_kCanvasHeight * web.window.devicePixelRatio.toDart).round().toJS;
+ _canvas = web.document.createElement('canvas') as web.HTMLCanvasElement;
+ _screenWidth = web.window.screen.width;
+ _canvas.width = _screenWidth;
+ _canvas.height = (_kCanvasHeight * web.window.devicePixelRatio).round();
_canvas.style
- ..setProperty('width'.toJS, '100%'.toJS)
- ..setProperty('height'.toJS, '${_kCanvasHeight}px'.toJS)
- ..setProperty('outline'.toJS, '1px solid green'.toJS);
- _ctx = _canvas.getContext('2d'.toJS)! as web.CanvasRenderingContext2D;
+ ..setProperty('width', '100%')
+ ..setProperty('height', '${_kCanvasHeight}px')
+ ..setProperty('outline', '1px solid green');
+ _ctx = _canvas.getContext('2d')! as web.CanvasRenderingContext2D;
// The amount of vertical space available on the chart. Because some
// outliers can be huge they can dwarf all the useful values. So we
@@ -250,15 +258,15 @@
/// A utility for drawing lines.
void drawLine(num x1, num y1, num x2, num y2) {
_ctx.beginPath();
- _ctx.moveTo(x1.toJS, y1.toJS);
- _ctx.lineTo(x2.toJS, y2.toJS);
+ _ctx.moveTo(x1.toDouble(), y1.toDouble());
+ _ctx.lineTo(x2.toDouble(), y2.toDouble());
_ctx.stroke();
}
/// Renders the timeseries into a `<canvas>` and returns the canvas element.
web.HTMLCanvasElement render() {
- _ctx.translate(0.toJS, (_kCanvasHeight * web.window.devicePixelRatio.toDart).toJS);
- _ctx.scale(1.toJS, (-web.window.devicePixelRatio.toDart).toJS);
+ _ctx.translate(0, _kCanvasHeight * web.window.devicePixelRatio);
+ _ctx.scale(1, -web.window.devicePixelRatio);
final double barWidth = _screenWidth / _stats.samples.length;
double xOffset = 0;
@@ -268,8 +276,7 @@
if (sample.isWarmUpValue) {
// Put gray background behind warm-up samples.
_ctx.fillStyle = 'rgba(200,200,200,1)'.toJS;
- _ctx.fillRect(xOffset.toJS, 0.toJS, barWidth.toJS,
- _normalized(_maxValueChartRange).toJS);
+ _ctx.fillRect(xOffset, 0, barWidth, _normalized(_maxValueChartRange));
}
if (sample.magnitude > _maxValueChartRange) {
@@ -283,13 +290,12 @@
_ctx.fillStyle = 'rgba(50,50,255,0.6)'.toJS;
}
- _ctx.fillRect(xOffset.toJS, 0.toJS, (barWidth - 1).toJS,
- _normalized(sample.magnitude).toJS);
+ _ctx.fillRect(xOffset, 0, barWidth - 1, _normalized(sample.magnitude));
xOffset += barWidth;
}
// Draw a horizontal solid line corresponding to the average.
- _ctx.lineWidth = 1.toJS;
+ _ctx.lineWidth = 1;
drawLine(0, _normalized(_stats.average), _screenWidth, _normalized(_stats.average));
// Draw a horizontal dashed line corresponding to the outlier cut off.
@@ -299,10 +305,10 @@
// Draw a light red band that shows the noise (1 stddev in each direction).
_ctx.fillStyle = 'rgba(255,50,50,0.3)'.toJS;
_ctx.fillRect(
- 0.toJS,
- _normalized(_stats.average * (1 - _stats.noise)).toJS,
- _screenWidth.toJS,
- _normalized(2 * _stats.average * _stats.noise).toJS,
+ 0,
+ _normalized(_stats.average * (1 - _stats.noise)),
+ _screenWidth.toDouble(),
+ _normalized(2 * _stats.average * _stats.noise),
);
return _canvas;
@@ -340,13 +346,13 @@
// 404 is expected in the following cases:
// - The benchmark is ran using plain `flutter run`, which does not provide "next-benchmark" handler.
// - We ran all benchmarks and the benchmark is telling us there are no more benchmarks to run.
- if (request.status.toDart != 200) {
+ if (request.status != 200) {
isInManualMode = true;
return kManualFallback;
}
isInManualMode = false;
- return request.responseText.toDart;
+ return request.responseText;
}
void _checkNotManualMode() {
@@ -389,7 +395,7 @@
mimeType: 'application/json',
sendData: json.encode(profile.toJson()),
);
- if (request.status.toDart != 200) {
+ if (request.status != 200) {
throw Exception(
'Failed to report profile data to benchmark server. '
'The server responded with status code ${request.status}.'
@@ -439,31 +445,31 @@
final web.XMLHttpRequest xhr = web.XMLHttpRequest();
method ??= 'GET';
- xhr.open(method.toJS, url.toJS, true.toJS);
+ xhr.open(method, url, true);
if (withCredentials != null) {
- xhr.withCredentials = withCredentials.toJS;
+ xhr.withCredentials = withCredentials;
}
if (responseType != null) {
- xhr.responseType = responseType.toJS;
+ xhr.responseType = responseType;
}
if (mimeType != null) {
- xhr.overrideMimeType(mimeType.toJS);
+ xhr.overrideMimeType(mimeType);
}
if (requestHeaders != null) {
requestHeaders.forEach((String header, String value) {
- xhr.setRequestHeader(header.toJS, value.toJS);
+ xhr.setRequestHeader(header, value);
});
}
- xhr.addEventListener('load'.toJS, (web.ProgressEvent e) {
+ xhr.addEventListener('load', (web.ProgressEvent e) {
completer.complete(xhr);
}.toJS);
- xhr.addEventListener('error'.toJS, (JSObject error) {
+ xhr.addEventListener('error', (JSObject error) {
return completer.completeError(error);
}.toJS);
diff --git a/dev/benchmarks/macrobenchmarks/pubspec.yaml b/dev/benchmarks/macrobenchmarks/pubspec.yaml
index f3c4cc7..b4c6c65 100644
--- a/dev/benchmarks/macrobenchmarks/pubspec.yaml
+++ b/dev/benchmarks/macrobenchmarks/pubspec.yaml
@@ -18,7 +18,7 @@
# flutter update-packages --force-upgrade
flutter_gallery_assets: 1.0.2
- web: 0.1.3-beta
+ web: 0.1.4-beta
async: 2.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -27,38 +27,39 @@
collection: 1.17.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
fake_async: 1.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
file: 6.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
matcher: 0.12.16 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.9.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path: 1.8.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
sync_http: 0.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- vm_service: 11.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ vm_service: 11.7.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
- test: 1.24.3
+ test: 1.24.4
integration_test:
sdk: flutter
- _fe_analyzer_shared: 61.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- analyzer: 5.13.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ _fe_analyzer_shared: 62.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ analyzer: 6.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
args: 2.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
convert: 3.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
coverage: 1.6.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
crypto: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ dart_internal: 0.2.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
frontend_server_client: 3.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
glob: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http_multi_server: 3.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http_parser: 4.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
io: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
logging: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
mime: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
node_preamble: 2.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -71,7 +72,7 @@
shelf_web_socket: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_map_stack_trace: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_maps: 0.10.12 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_core: 0.5.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_core: 0.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -210,4 +211,4 @@
fonts:
- asset: packages/flutter_gallery_assets/fonts/GalleryIcons.ttf
-# PUBSPEC CHECKSUM: 9626
+# PUBSPEC CHECKSUM: e1ba
diff --git a/dev/benchmarks/microbenchmarks/ios/Runner/Info.plist b/dev/benchmarks/microbenchmarks/ios/Runner/Info.plist
index 57ca345..8245271 100644
--- a/dev/benchmarks/microbenchmarks/ios/Runner/Info.plist
+++ b/dev/benchmarks/microbenchmarks/ios/Runner/Info.plist
@@ -39,8 +39,6 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
- <key>UIViewControllerBasedStatusBarAppearance</key>
- <false/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
diff --git a/dev/benchmarks/microbenchmarks/lib/foundation/timeline_bench.dart b/dev/benchmarks/microbenchmarks/lib/foundation/timeline_bench.dart
index 339a46c..7c9eb4a 100644
--- a/dev/benchmarks/microbenchmarks/lib/foundation/timeline_bench.dart
+++ b/dev/benchmarks/microbenchmarks/lib/foundation/timeline_bench.dart
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-import 'dart:developer';
+import 'package:flutter/foundation.dart';
import '../common.dart';
@@ -16,8 +16,8 @@
final Stopwatch watch = Stopwatch();
watch.start();
for (int i = 0; i < _kNumIterations; i += 1) {
- Timeline.startSync('foo');
- Timeline.finishSync();
+ FlutterTimeline.startSync('foo');
+ FlutterTimeline.finishSync();
}
watch.stop();
@@ -31,14 +31,14 @@
watch.reset();
watch.start();
for (int i = 0; i < _kNumIterations; i += 1) {
- Timeline.startSync('foo', arguments: <String, dynamic>{
+ FlutterTimeline.startSync('foo', arguments: <String, dynamic>{
'int': 1234,
'double': 0.3,
'list': <int>[1, 2, 3, 4],
'map': <String, dynamic>{'map': true},
'bool': false,
});
- Timeline.finishSync();
+ FlutterTimeline.finishSync();
}
watch.stop();
diff --git a/dev/benchmarks/microbenchmarks/lib/language/compute_bench.dart b/dev/benchmarks/microbenchmarks/lib/language/compute_bench.dart
index aa9c4312..36e8ef7 100644
--- a/dev/benchmarks/microbenchmarks/lib/language/compute_bench.dart
+++ b/dev/benchmarks/microbenchmarks/lib/language/compute_bench.dart
@@ -12,9 +12,10 @@
class Data {
Data(this.value);
- Map<String, dynamic> toJson() => <String, dynamic>{ 'value': value };
-
final int value;
+
+ @override
+ String toString() => 'Data($value)';
}
List<Data> test(int length) {
diff --git a/dev/benchmarks/microbenchmarks/pubspec.yaml b/dev/benchmarks/microbenchmarks/pubspec.yaml
index 3c45e96..aaf8d8f 100644
--- a/dev/benchmarks/microbenchmarks/pubspec.yaml
+++ b/dev/benchmarks/microbenchmarks/pubspec.yaml
@@ -12,11 +12,11 @@
sdk: flutter
stocks:
path: ../test_apps/stocks
- test: 1.24.3
+ test: 1.24.4
flutter_gallery_assets: 1.0.2
- _fe_analyzer_shared: 61.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- analyzer: 5.13.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ _fe_analyzer_shared: 62.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ analyzer: 6.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
args: 2.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
async: 2.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -26,6 +26,7 @@
convert: 3.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
coverage: 1.6.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
crypto: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ dart_internal: 0.2.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
fake_async: 1.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
file: 6.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
frontend_server_client: 3.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -53,16 +54,17 @@
source_map_stack_trace: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_maps: 0.10.12 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_core: 0.5.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_core: 0.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- vm_service: 11.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ vm_service: 11.7.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -136,4 +138,4 @@
- packages/flutter_gallery_assets/people/square/stella.png
- packages/flutter_gallery_assets/people/square/trevor.png
-# PUBSPEC CHECKSUM: 2948
+# PUBSPEC CHECKSUM: 5532
diff --git a/dev/benchmarks/multiple_flutters/module/pubspec.yaml b/dev/benchmarks/multiple_flutters/module/pubspec.yaml
index c1a0570..2e02625 100644
--- a/dev/benchmarks/multiple_flutters/module/pubspec.yaml
+++ b/dev/benchmarks/multiple_flutters/module/pubspec.yaml
@@ -21,12 +21,11 @@
file: 6.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http: 0.13.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http_parser: 4.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.9.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path: 1.8.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path_provider: 2.0.15 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- path_provider_android: 2.0.21 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ path_provider_android: 2.0.27 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path_provider_foundation: 2.2.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path_provider_linux: 2.1.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path_provider_platform_interface: 2.0.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -39,7 +38,8 @@
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- win32: 5.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ win32: 5.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
xdg_directories: 1.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
flutter:
@@ -50,4 +50,4 @@
androidPackage: com.example.multiple_flutters_module
iosBundleIdentifier: com.example.multipleFluttersModule
-# PUBSPEC CHECKSUM: 288e
+# PUBSPEC CHECKSUM: 7bba
diff --git a/dev/benchmarks/platform_channels_benchmarks/pubspec.yaml b/dev/benchmarks/platform_channels_benchmarks/pubspec.yaml
index c798fd8..9a1e0a2 100644
--- a/dev/benchmarks/platform_channels_benchmarks/pubspec.yaml
+++ b/dev/benchmarks/platform_channels_benchmarks/pubspec.yaml
@@ -16,8 +16,8 @@
path: ../microbenchmarks
cupertino_icons: 1.0.5
- _fe_analyzer_shared: 61.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- analyzer: 5.13.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ _fe_analyzer_shared: 62.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ analyzer: 6.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
args: 2.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
async: 2.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -27,6 +27,7 @@
convert: 3.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
coverage: 1.6.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
crypto: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ dart_internal: 0.2.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
fake_async: 1.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
file: 6.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
flutter_gallery_assets: 1.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -53,17 +54,18 @@
source_map_stack_trace: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_maps: 0.10.12 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test: 1.24.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_core: 0.5.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test: 1.24.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_core: 0.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- vm_service: 11.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ vm_service: 11.7.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -73,4 +75,4 @@
flutter:
uses-material-design: true
-# PUBSPEC CHECKSUM: 2d33
+# PUBSPEC CHECKSUM: 051d
diff --git a/dev/benchmarks/platform_views_layout/ios/Runner/Info.plist b/dev/benchmarks/platform_views_layout/ios/Runner/Info.plist
index c2c46f5..08da00d 100644
--- a/dev/benchmarks/platform_views_layout/ios/Runner/Info.plist
+++ b/dev/benchmarks/platform_views_layout/ios/Runner/Info.plist
@@ -39,8 +39,6 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
- <key>UIViewControllerBasedStatusBarAppearance</key>
- <false/>
<key>io.flutter.embedded_views_preview</key>
<true/>
<key>io.flutter.metal_preview</key>
diff --git a/dev/benchmarks/platform_views_layout/lib/main.dart b/dev/benchmarks/platform_views_layout/lib/main.dart
index 9fd59bf..4eb4f81 100644
--- a/dev/benchmarks/platform_views_layout/lib/main.dart
+++ b/dev/benchmarks/platform_views_layout/lib/main.dart
@@ -5,7 +5,6 @@
import 'dart:io';
import 'package:flutter/material.dart';
-import 'package:flutter/scheduler.dart' show timeDilation;
void main() {
runApp(
@@ -31,12 +30,6 @@
home: const PlatformViewLayout(),
);
}
-
- void toggleAnimationSpeed() {
- setState(() {
- timeDilation = (timeDilation != 1.0) ? 1.0 : 5.0;
- });
- }
}
class PlatformViewLayout extends StatelessWidget {
diff --git a/dev/benchmarks/platform_views_layout/lib/main_non_intersecting.dart b/dev/benchmarks/platform_views_layout/lib/main_non_intersecting.dart
index 63156e8..9107e9a 100644
--- a/dev/benchmarks/platform_views_layout/lib/main_non_intersecting.dart
+++ b/dev/benchmarks/platform_views_layout/lib/main_non_intersecting.dart
@@ -5,7 +5,6 @@
import 'dart:io';
import 'package:flutter/material.dart';
-import 'package:flutter/scheduler.dart' show timeDilation;
void main() {
runApp(
@@ -31,12 +30,6 @@
home: const PlatformViewLayout(),
);
}
-
- void toggleAnimationSpeed() {
- setState(() {
- timeDilation = (timeDilation != 1.0) ? 1.0 : 5.0;
- });
- }
}
class PlatformViewLayout extends StatelessWidget {
diff --git a/dev/benchmarks/platform_views_layout/pubspec.yaml b/dev/benchmarks/platform_views_layout/pubspec.yaml
index ef35286..6fc9f64 100644
--- a/dev/benchmarks/platform_views_layout/pubspec.yaml
+++ b/dev/benchmarks/platform_views_layout/pubspec.yaml
@@ -21,40 +21,42 @@
characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
collection: 1.17.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
file: 6.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
matcher: 0.12.16 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.9.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path: 1.8.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
sync_http: 0.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- vm_service: 11.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ vm_service: 11.7.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
flutter_test:
sdk: flutter
- test: 1.24.3
+ test: 1.24.4
- _fe_analyzer_shared: 61.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- analyzer: 5.13.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ _fe_analyzer_shared: 62.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ analyzer: 6.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
args: 2.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
clock: 1.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
convert: 3.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
coverage: 1.6.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
crypto: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ dart_internal: 0.2.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
fake_async: 1.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
frontend_server_client: 3.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
glob: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http_multi_server: 3.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http_parser: 4.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
io: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
logging: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
mime: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
node_preamble: 2.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -67,7 +69,7 @@
shelf_web_socket: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_map_stack_trace: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_maps: 0.10.12 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_core: 0.5.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_core: 0.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -80,4 +82,4 @@
- packages/flutter_gallery_assets/people/square/ali.png
- packages/flutter_gallery_assets/places/india_chettinad_silk_maker.png
-# PUBSPEC CHECKSUM: 43d0
+# PUBSPEC CHECKSUM: e1ba
diff --git a/dev/benchmarks/platform_views_layout_hybrid_composition/ios/Runner/Info.plist b/dev/benchmarks/platform_views_layout_hybrid_composition/ios/Runner/Info.plist
index 028706d..f2d51ed 100644
--- a/dev/benchmarks/platform_views_layout_hybrid_composition/ios/Runner/Info.plist
+++ b/dev/benchmarks/platform_views_layout_hybrid_composition/ios/Runner/Info.plist
@@ -39,8 +39,6 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
- <key>UIViewControllerBasedStatusBarAppearance</key>
- <false/>
<key>io.flutter.embedded_views_preview</key>
<true/>
<key>io.flutter.metal_preview</key>
diff --git a/dev/benchmarks/platform_views_layout_hybrid_composition/lib/main.dart b/dev/benchmarks/platform_views_layout_hybrid_composition/lib/main.dart
index 98cdb0c..f56bc63 100644
--- a/dev/benchmarks/platform_views_layout_hybrid_composition/lib/main.dart
+++ b/dev/benchmarks/platform_views_layout_hybrid_composition/lib/main.dart
@@ -5,7 +5,6 @@
import 'dart:io';
import 'package:flutter/material.dart';
-import 'package:flutter/scheduler.dart' show timeDilation;
import 'package:flutter_driver/driver_extension.dart';
import 'android_platform_view.dart';
@@ -35,12 +34,6 @@
home: const PlatformViewLayout(),
);
}
-
- void toggleAnimationSpeed() {
- setState(() {
- timeDilation = (timeDilation != 1.0) ? 1.0 : 5.0;
- });
- }
}
class PlatformViewLayout extends StatelessWidget {
diff --git a/dev/benchmarks/platform_views_layout_hybrid_composition/pubspec.yaml b/dev/benchmarks/platform_views_layout_hybrid_composition/pubspec.yaml
index df64cc1..f0cf52b 100644
--- a/dev/benchmarks/platform_views_layout_hybrid_composition/pubspec.yaml
+++ b/dev/benchmarks/platform_views_layout_hybrid_composition/pubspec.yaml
@@ -21,40 +21,42 @@
characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
collection: 1.17.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
file: 6.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
matcher: 0.12.16 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.9.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path: 1.8.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
sync_http: 0.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- vm_service: 11.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ vm_service: 11.7.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
flutter_test:
sdk: flutter
- test: 1.24.3
+ test: 1.24.4
- _fe_analyzer_shared: 61.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- analyzer: 5.13.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ _fe_analyzer_shared: 62.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ analyzer: 6.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
args: 2.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
clock: 1.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
convert: 3.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
coverage: 1.6.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
crypto: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ dart_internal: 0.2.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
fake_async: 1.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
frontend_server_client: 3.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
glob: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http_multi_server: 3.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http_parser: 4.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
io: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
logging: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
mime: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
node_preamble: 2.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -67,7 +69,7 @@
shelf_web_socket: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_map_stack_trace: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_maps: 0.10.12 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_core: 0.5.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_core: 0.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -80,4 +82,4 @@
- packages/flutter_gallery_assets/people/square/ali.png
- packages/flutter_gallery_assets/places/india_chettinad_silk_maker.png
-# PUBSPEC CHECKSUM: 43d0
+# PUBSPEC CHECKSUM: e1ba
diff --git a/dev/benchmarks/test_apps/stocks/ios/Runner/Info.plist b/dev/benchmarks/test_apps/stocks/ios/Runner/Info.plist
index ea08bb1..a110ad2 100644
--- a/dev/benchmarks/test_apps/stocks/ios/Runner/Info.plist
+++ b/dev/benchmarks/test_apps/stocks/ios/Runner/Info.plist
@@ -39,8 +39,6 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
- <key>UIViewControllerBasedStatusBarAppearance</key>
- <false/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
diff --git a/dev/benchmarks/test_apps/stocks/lib/main.dart b/dev/benchmarks/test_apps/stocks/lib/main.dart
index 159de8c..536e906 100644
--- a/dev/benchmarks/test_apps/stocks/lib/main.dart
+++ b/dev/benchmarks/test_apps/stocks/lib/main.dart
@@ -50,11 +50,13 @@
switch (_configuration.stockMode) {
case StockMode.optimistic:
return ThemeData(
+ useMaterial3: false,
brightness: Brightness.light,
primarySwatch: Colors.purple,
);
case StockMode.pessimistic:
return ThemeData(
+ useMaterial3: false,
brightness: Brightness.dark,
primarySwatch: Colors.purple,
);
diff --git a/dev/benchmarks/test_apps/stocks/pubspec.yaml b/dev/benchmarks/test_apps/stocks/pubspec.yaml
index fb4e985..c54dd5f 100644
--- a/dev/benchmarks/test_apps/stocks/pubspec.yaml
+++ b/dev/benchmarks/test_apps/stocks/pubspec.yaml
@@ -17,7 +17,6 @@
clock: 1.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
collection: 1.17.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http_parser: 4.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.9.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path: 1.8.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -26,27 +25,30 @@
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
flutter_test:
sdk: flutter
flutter_driver:
sdk: flutter
- test: 1.24.3
+ test: 1.24.4
- _fe_analyzer_shared: 61.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- analyzer: 5.13.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ _fe_analyzer_shared: 62.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ analyzer: 6.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
args: 2.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
convert: 3.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
coverage: 1.6.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
crypto: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ dart_internal: 0.2.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
fake_async: 1.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
file: 6.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
frontend_server_client: 3.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
glob: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http_multi_server: 3.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
io: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
logging: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
matcher: 0.12.16 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
mime: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -60,12 +62,12 @@
shelf_web_socket: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_map_stack_trace: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_maps: 0.10.12 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
sync_http: 0.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_core: 0.5.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- vm_service: 11.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_core: 0.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ vm_service: 11.7.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -75,4 +77,4 @@
flutter:
uses-material-design: true
-# PUBSPEC CHECKSUM: f8f2
+# PUBSPEC CHECKSUM: 67dc
diff --git a/dev/bots/allowlist.dart b/dev/bots/allowlist.dart
index 966c3d8..ddd2b66 100644
--- a/dev/bots/allowlist.dart
+++ b/dev/bots/allowlist.dart
@@ -31,7 +31,6 @@
'fuchsia_remote_debug_protocol',
'integration_test',
'intl',
- 'js',
'matcher',
'material_color_utilities',
'meta',
diff --git a/dev/bots/pubspec.yaml b/dev/bots/pubspec.yaml
index 68ecda6..2b4fbe7 100644
--- a/dev/bots/pubspec.yaml
+++ b/dev/bots/pubspec.yaml
@@ -15,11 +15,11 @@
path: 1.8.3
platform: 3.1.0
process: 4.2.4
- test: 1.24.3
+ test: 1.24.4
_discoveryapis_commons: 1.0.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- _fe_analyzer_shared: 61.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- analyzer: 5.13.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ _fe_analyzer_shared: 62.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ analyzer: 6.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
archive: 3.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
async: 2.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -28,10 +28,11 @@
collection: 1.17.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
convert: 3.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
coverage: 1.6.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ dart_internal: 0.2.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
equatable: 2.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
file: 6.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
frontend_server_client: 3.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- gcloud: 0.8.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ gcloud: 0.8.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
glob: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
googleapis: 3.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
googleapis_auth: 1.4.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -42,7 +43,7 @@
json_annotation: 4.8.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
logging: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
matcher: 0.12.16 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- metrics_center: 1.0.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ metrics_center: 1.0.10 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
mime: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
node_preamble: 2.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
package_config: 2.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -56,20 +57,20 @@
source_map_stack_trace: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_maps: 0.10.12 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_core: 0.5.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_core: 0.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- vm_service: 11.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ vm_service: 11.7.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- web: 0.1.3-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
- test_api: 0.6.0
+ test_api: 0.6.1
-# PUBSPEC CHECKSUM: d01f
+# PUBSPEC CHECKSUM: c2dc
diff --git a/dev/bots/test.dart b/dev/bots/test.dart
index b37bdec..c994041 100644
--- a/dev/bots/test.dart
+++ b/dev/bots/test.dart
@@ -277,7 +277,8 @@
}
final String _luciBotId = Platform.environment['SWARMING_BOT_ID'] ?? '';
-final bool _runningInDartHHHBot = _luciBotId.startsWith('luci-dart-');
+final bool _runningInDartHHHBot =
+ _luciBotId.startsWith('luci-dart-') || _luciBotId.startsWith('dart-tests-');
/// Verify the Flutter Engine is the revision in
/// bin/cache/internal/engine.version.
@@ -970,6 +971,7 @@
await runTracingTests();
await runFixTests('flutter');
await runFixTests('flutter_test');
+ await runFixTests('integration_test');
await runPrivateTests();
}
@@ -1374,6 +1376,14 @@
pos = javaScript.indexOf(word, pos);
}
+ // The following are classes from `timeline.dart` that should be treeshaken
+ // off unless the app (typically a benchmark) uses methods that need them.
+ expect(javaScript.contains('AggregatedTimedBlock'), false);
+ expect(javaScript.contains('AggregatedTimings'), false);
+ expect(javaScript.contains('_BlockBuffer'), false);
+ expect(javaScript.contains('_StringListChain'), false);
+ expect(javaScript.contains('_Float64ListChain'), false);
+
const int kMaxExpectedDebugFillProperties = 11;
if (count > kMaxExpectedDebugFillProperties) {
throw Exception(
diff --git a/dev/ci/docker_linux/Dockerfile b/dev/ci/docker_linux/Dockerfile
index 23db22e..db58a1a 100644
--- a/dev/ci/docker_linux/Dockerfile
+++ b/dev/ci/docker_linux/Dockerfile
@@ -12,7 +12,7 @@
# Last manual update 2021-09-24 (changing this comment will re-build image)
-FROM ubuntu:focal@sha256:b795f8e0caaaacad9859a9a38fe1c78154f8301fdaf0872eaf1520d66d9c0b98
+FROM ubuntu:focal@sha256:f8f658407c35733471596f25fdb4ed748b80e545ab57e84efbdb1dbbb01bd70e
MAINTAINER Flutter Developers <flutter-dev@googlegroups.com>
ENV TZ=America/Los_Angeles
diff --git a/dev/conductor/core/bin/packages_autoroller.dart b/dev/conductor/core/bin/packages_autoroller.dart
index db9635e..a890927 100644
--- a/dev/conductor/core/bin/packages_autoroller.dart
+++ b/dev/conductor/core/bin/packages_autoroller.dart
@@ -15,8 +15,8 @@
const String kTokenOption = 'token';
const String kGithubClient = 'github-client';
-const String kMirrorRemote = 'mirror-remote';
const String kUpstreamRemote = 'upstream-remote';
+const String kGithubAccountName = 'flutter-pub-roller-bot';
Future<void> main(List<String> args) {
return run(args);
@@ -39,11 +39,10 @@
help: 'Path to GitHub CLI client. If not provided, it is assumed `gh` is '
'present on the PATH.',
);
+ // TODO(fujino): delete after recipe has been migrated to stop passing this
parser.addOption(
- kMirrorRemote,
- help: 'The mirror git remote that the feature branch will be pushed to. '
- 'Required',
- mandatory: true,
+ 'mirror-remote',
+ help: '(Deprecated) this is now a no-op. To change the account, edit this tool.',
);
parser.addOption(
kUpstreamRemote,
@@ -64,7 +63,7 @@
rethrow;
}
- final String mirrorUrl = results[kMirrorRemote]! as String;
+ const String mirrorUrl = 'https://github.com/flutter-pub-roller-bot/flutter.git';
final String upstreamUrl = results[kUpstreamRemote]! as String;
final String tokenPath = results[kTokenOption]! as String;
final File tokenFile = fs.file(tokenPath);
@@ -81,7 +80,7 @@
}
final FrameworkRepository framework = FrameworkRepository(
- _localCheckouts,
+ _localCheckouts(token),
mirrorRemote: Remote.mirror(mirrorUrl),
upstreamRemote: Remote.upstream(upstreamUrl),
);
@@ -92,6 +91,7 @@
orgName: _parseOrgName(mirrorUrl),
token: token,
processManager: processManager,
+ githubUsername: kGithubAccountName,
).roll();
}
@@ -106,7 +106,7 @@
return match.group(1)!;
}
-Checkouts get _localCheckouts {
+Checkouts _localCheckouts(String token) {
const FileSystem fileSystem = LocalFileSystem();
const ProcessManager processManager = LocalProcessManager();
const Platform platform = LocalPlatform();
@@ -114,6 +114,7 @@
stdout: io.stdout,
stderr: io.stderr,
stdin: io.stdin,
+ filter: (String message) => message.replaceAll(token, '[GitHub TOKEN]'),
);
return Checkouts(
fileSystem: fileSystem,
diff --git a/dev/conductor/core/lib/src/packages_autoroller.dart b/dev/conductor/core/lib/src/packages_autoroller.dart
index 2ab002d..b39a159 100644
--- a/dev/conductor/core/lib/src/packages_autoroller.dart
+++ b/dev/conductor/core/lib/src/packages_autoroller.dart
@@ -20,7 +20,7 @@
required this.framework,
required this.orgName,
required this.processManager,
- this.githubUsername = 'fluttergithubbot',
+ required this.githubUsername,
Stdio? stdio,
}) {
this.stdio = stdio ?? VerboseStdio.local();
@@ -111,7 +111,7 @@
Future<bool> updatePackages({
bool verbose = true,
}) async {
- final String author = '$githubUsername <$githubUsername@gmail.com>';
+ final String author = '$githubUsername <$githubUsername@google.com>';
await framework.newBranch(await featureBranchName);
final io.Process flutterProcess = await framework.streamFlutter(<String>[
diff --git a/dev/conductor/core/lib/src/stdio.dart b/dev/conductor/core/lib/src/stdio.dart
index 8777b91..df8f81d 100644
--- a/dev/conductor/core/lib/src/stdio.dart
+++ b/dev/conductor/core/lib/src/stdio.dart
@@ -70,6 +70,7 @@
required this.stdout,
required this.stderr,
required this.stdin,
+ this.filter,
});
factory VerboseStdio.local() => VerboseStdio(
@@ -82,26 +83,50 @@
final io.Stdout stderr;
final io.Stdin stdin;
+ /// If provided, all messages will be passed through this function before being logged.
+ final String Function(String)? filter;
+
@override
void printError(String message) {
+ if (filter != null) {
+ message = filter!(message);
+ }
super.printError(message);
stderr.writeln(message);
}
@override
+ void printWarning(String message) {
+ if (filter != null) {
+ message = filter!(message);
+ }
+ super.printWarning(message);
+ stderr.writeln(message);
+ }
+
+ @override
void printStatus(String message) {
+ if (filter != null) {
+ message = filter!(message);
+ }
super.printStatus(message);
stdout.writeln(message);
}
@override
void printTrace(String message) {
+ if (filter != null) {
+ message = filter!(message);
+ }
super.printTrace(message);
stdout.writeln(message);
}
@override
void write(String message) {
+ if (filter != null) {
+ message = filter!(message);
+ }
super.write(message);
stdout.write(message);
}
diff --git a/dev/conductor/core/pubspec.yaml b/dev/conductor/core/pubspec.yaml
index c745468..831df5d 100644
--- a/dev/conductor/core/pubspec.yaml
+++ b/dev/conductor/core/pubspec.yaml
@@ -14,7 +14,7 @@
meta: 1.9.1
path: 1.8.3
process: 4.2.4
- protobuf: 2.1.0
+ protobuf: 3.0.0
async: 2.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
clock: 1.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -30,14 +30,15 @@
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
- test: 1.24.3
- test_api: 0.6.0
+ test: 1.24.4
+ test_api: 0.6.1
- _fe_analyzer_shared: 61.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- analyzer: 5.13.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ _fe_analyzer_shared: 62.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ analyzer: 6.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
convert: 3.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
coverage: 1.6.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ dart_internal: 0.2.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
frontend_server_client: 3.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
glob: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http_multi_server: 3.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -56,13 +57,13 @@
shelf_web_socket: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_map_stack_trace: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_maps: 0.10.12 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_core: 0.5.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- vm_service: 11.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_core: 0.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ vm_service: 11.7.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
-# PUBSPEC CHECKSUM: d02a
+# PUBSPEC CHECKSUM: eebd
diff --git a/dev/conductor/core/test/common.dart b/dev/conductor/core/test/common.dart
index 9cf66ff..f1a2f39 100644
--- a/dev/conductor/core/test/common.dart
+++ b/dev/conductor/core/test/common.dart
@@ -6,6 +6,7 @@
import 'package:conductor_core/src/stdio.dart';
import 'package:test/test.dart';
+export 'package:test/fake.dart';
export 'package:test/test.dart' hide isInstanceOf;
export '../../../../packages/flutter_tools/test/src/fake_process_manager.dart';
diff --git a/dev/conductor/core/test/next_test.dart b/dev/conductor/core/test/next_test.dart
index f124aa2..dee3a2e 100644
--- a/dev/conductor/core/test/next_test.dart
+++ b/dev/conductor/core/test/next_test.dart
@@ -1227,34 +1227,10 @@
}
/// A [Stdio] that will throw an exception if any of its methods are called.
-class _UnimplementedStdio implements Stdio {
- const _UnimplementedStdio();
+class _UnimplementedStdio extends Fake implements Stdio {
+ _UnimplementedStdio();
- static const _UnimplementedStdio _instance = _UnimplementedStdio();
- static _UnimplementedStdio get instance => _instance;
-
- Never _throw() => throw Exception('Unimplemented!');
-
- @override
- List<String> get logs => _throw();
-
- @override
- void printError(String message) => _throw();
-
- @override
- void printWarning(String message) => _throw();
-
- @override
- void printStatus(String message) => _throw();
-
- @override
- void printTrace(String message) => _throw();
-
- @override
- void write(String message) => _throw();
-
- @override
- String readLineSync() => _throw();
+ static final _UnimplementedStdio instance = _UnimplementedStdio();
}
class _TestRepository extends Repository {
diff --git a/dev/conductor/core/test/packages_autoroller_test.dart b/dev/conductor/core/test/packages_autoroller_test.dart
index 0b1d54d..9ce7a28 100644
--- a/dev/conductor/core/test/packages_autoroller_test.dart
+++ b/dev/conductor/core/test/packages_autoroller_test.dart
@@ -63,6 +63,7 @@
orgName: orgName,
processManager: processManager,
stdio: stdio,
+ githubUsername: 'flutter-pub-roller-bot',
);
});
@@ -199,7 +200,7 @@
'pr',
'list',
'--author',
- 'fluttergithubbot',
+ 'flutter-pub-roller-bot',
'--repo',
'flutter/flutter',
'--state',
@@ -216,7 +217,7 @@
await controller.stream.drain();
await rollFuture;
expect(processManager, hasNoRemainingExpectations);
- expect(stdio.stdout, contains('fluttergithubbot already has open tool PRs'));
+ expect(stdio.stdout, contains('flutter-pub-roller-bot already has open tool PRs'));
expect(stdio.stdout, contains(r'[{number: 123}]'));
});
@@ -239,7 +240,7 @@
'pr',
'list',
'--author',
- 'fluttergithubbot',
+ 'flutter-pub-roller-bot',
'--repo',
'flutter/flutter',
'--state',
@@ -335,7 +336,7 @@
'pr',
'list',
'--author',
- 'fluttergithubbot',
+ 'flutter-pub-roller-bot',
'--repo',
'flutter/flutter',
'--state',
@@ -427,7 +428,7 @@
'commit',
'--message',
'roll packages',
- '--author="fluttergithubbot <fluttergithubbot@gmail.com>"',
+ '--author="flutter-pub-roller-bot <flutter-pub-roller-bot@google.com>"',
]),
const FakeCommand(command: <String>[
'git',
@@ -475,12 +476,11 @@
group('command argument validations', () {
const String tokenPath = '/path/to/token';
- const String mirrorRemote = 'https://githost.com/org/project';
test('validates that file exists at --token option', () async {
await expectLater(
() => run(
- <String>['--token', tokenPath, '--mirror-remote', mirrorRemote],
+ <String>['--token', tokenPath],
fs: fileSystem,
processManager: processManager,
),
@@ -499,7 +499,7 @@
..writeAsStringSync('');
await expectLater(
() => run(
- <String>['--token', tokenPath, '--mirror-remote', mirrorRemote],
+ <String>['--token', tokenPath],
fs: fileSystem,
processManager: processManager,
),
@@ -512,4 +512,35 @@
expect(processManager, hasNoRemainingExpectations);
});
});
+
+ test('VerboseStdio logger can filter out confidential pattern', () async {
+ const String token = 'secret';
+ const String replacement = 'replacement';
+ final VerboseStdio stdio = VerboseStdio(
+ stdin: _NoOpStdin(),
+ stderr: _NoOpStdout(),
+ stdout: _NoOpStdout(),
+ filter: (String msg) => msg.replaceAll(token, replacement),
+ );
+ stdio.printStatus('Hello');
+ expect(stdio.logs.last, '[status] Hello');
+
+ stdio.printStatus('Using $token');
+ expect(stdio.logs.last, '[status] Using $replacement');
+
+ stdio.printWarning('Using $token');
+ expect(stdio.logs.last, '[warning] Using $replacement');
+
+ stdio.printError('Using $token');
+ expect(stdio.logs.last, '[error] Using $replacement');
+
+ stdio.printTrace('Using $token');
+ expect(stdio.logs.last, '[trace] Using $replacement');
+ });
+}
+
+class _NoOpStdin extends Fake implements io.Stdin {}
+class _NoOpStdout extends Fake implements io.Stdout {
+ @override
+ void writeln([Object? object]) {}
}
diff --git a/dev/customer_testing/pubspec.yaml b/dev/customer_testing/pubspec.yaml
index 99b0888..2c45122 100644
--- a/dev/customer_testing/pubspec.yaml
+++ b/dev/customer_testing/pubspec.yaml
@@ -18,14 +18,15 @@
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
- test: 1.24.3
+ test: 1.24.4
- _fe_analyzer_shared: 61.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- analyzer: 5.13.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ _fe_analyzer_shared: 62.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ analyzer: 6.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
convert: 3.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
coverage: 1.6.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
crypto: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ dart_internal: 0.2.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
frontend_server_client: 3.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http_multi_server: 3.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http_parser: 4.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -44,15 +45,15 @@
shelf_web_socket: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_map_stack_trace: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_maps: 0.10.12 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_core: 0.5.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_core: 0.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- vm_service: 11.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ vm_service: 11.7.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
-# PUBSPEC CHECKSUM: 8c77
+# PUBSPEC CHECKSUM: 940b
diff --git a/dev/devicelab/bin/tasks/platform_views_scroll_perf_impeller__timeline_summary.dart b/dev/devicelab/bin/tasks/platform_views_scroll_perf_impeller__timeline_summary.dart
new file mode 100644
index 0000000..95bd8ad
--- /dev/null
+++ b/dev/devicelab/bin/tasks/platform_views_scroll_perf_impeller__timeline_summary.dart
@@ -0,0 +1,12 @@
+// Copyright 2014 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'package:flutter_devicelab/framework/devices.dart';
+import 'package:flutter_devicelab/framework/framework.dart';
+import 'package:flutter_devicelab/tasks/perf_tests.dart';
+
+Future<void> main() async {
+ deviceOperatingSystem = DeviceOperatingSystem.android;
+ await task(createAndroidTextureScrollPerfTest(enableImpeller: true));
+}
diff --git a/dev/devicelab/bin/tasks/web_benchmarks_canvaskit.dart b/dev/devicelab/bin/tasks/web_benchmarks_canvaskit.dart
index 313f7e2..1aabf51 100644
--- a/dev/devicelab/bin/tasks/web_benchmarks_canvaskit.dart
+++ b/dev/devicelab/bin/tasks/web_benchmarks_canvaskit.dart
@@ -8,6 +8,9 @@
/// Runs all Web benchmarks using the CanvasKit rendering backend.
Future<void> main() async {
await task(() async {
- return runWebBenchmark(useCanvasKit: true);
+ return runWebBenchmark((
+ webRenderer: 'canvaskit',
+ useWasm: false
+ ));
});
}
diff --git a/dev/devicelab/bin/tasks/web_benchmarks_html.dart b/dev/devicelab/bin/tasks/web_benchmarks_html.dart
index 8cca0d6..b7719cc 100644
--- a/dev/devicelab/bin/tasks/web_benchmarks_html.dart
+++ b/dev/devicelab/bin/tasks/web_benchmarks_html.dart
@@ -8,6 +8,9 @@
/// Runs all Web benchmarks using the HTML rendering backend.
Future<void> main() async {
await task(() async {
- return runWebBenchmark(useCanvasKit: false);
+ return runWebBenchmark((
+ webRenderer: 'html',
+ useWasm: false
+ ));
});
}
diff --git a/dev/devicelab/bin/tasks/web_benchmarks_skwasm.dart b/dev/devicelab/bin/tasks/web_benchmarks_skwasm.dart
new file mode 100644
index 0000000..256634a
--- /dev/null
+++ b/dev/devicelab/bin/tasks/web_benchmarks_skwasm.dart
@@ -0,0 +1,16 @@
+// Copyright 2014 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'package:flutter_devicelab/framework/framework.dart';
+import 'package:flutter_devicelab/tasks/web_benchmarks.dart';
+
+/// Runs all Web benchmarks using the Skwasm rendering backend.
+Future<void> main() async {
+ await task(() async {
+ return runWebBenchmark((
+ webRenderer: 'skwasm',
+ useWasm: true
+ ));
+ });
+}
diff --git a/dev/devicelab/lib/framework/browser.dart b/dev/devicelab/lib/framework/browser.dart
index 3180bb7..9d4581f 100644
--- a/dev/devicelab/lib/framework/browser.dart
+++ b/dev/devicelab/lib/framework/browser.dart
@@ -25,6 +25,7 @@
this.windowHeight = 1024,
this.headless,
this.debugPort,
+ this.enableWasmGC = false,
});
/// If not null passed as `--user-data-dir`.
@@ -53,6 +54,9 @@
/// mode without a debug port, Chrome quits immediately. For most tests it is
/// typical to set [headless] to true and set a non-null debug port.
final int? debugPort;
+
+ /// Whether to enable experimental WasmGC flags
+ final bool enableWasmGC;
}
/// A function called when the Chrome process encounters an error.
@@ -104,6 +108,8 @@
'--no-default-browser-check',
'--disable-default-apps',
'--disable-translate',
+ if (options.enableWasmGC)
+ '--js-flags=--experimental-wasm-gc',
];
final io.Process chromeProcess = await _spawnChromiumProcess(
diff --git a/dev/devicelab/lib/tasks/perf_tests.dart b/dev/devicelab/lib/tasks/perf_tests.dart
index 04c8466..20c8389 100644
--- a/dev/devicelab/lib/tasks/perf_tests.dart
+++ b/dev/devicelab/lib/tasks/perf_tests.dart
@@ -70,12 +70,14 @@
).run;
}
-TaskFunction createAndroidTextureScrollPerfTest() {
+TaskFunction createAndroidTextureScrollPerfTest({bool? enableImpeller}) {
return PerfTest(
'${flutterDirectory.path}/dev/benchmarks/platform_views_layout',
'test_driver/android_view_scroll_perf.dart',
'platform_views_scroll_perf',
testDriver: 'test_driver/scroll_perf_test.dart',
+ needsFullTimeline: false,
+ enableImpeller: enableImpeller,
).run;
}
@@ -769,6 +771,15 @@
const int maxFailures = 3;
int currentFailures = 0;
for (int i = 0; i < iterations; i += 1) {
+ // Startup should not take more than a few minutes. After 10 minutes,
+ // take a screenshot to help debug.
+ final Timer timer = Timer(const Duration(minutes: 10), () async {
+ print('Startup not completed within 10 minutes. Taking a screenshot...');
+ await _flutterScreenshot(
+ device.deviceId,
+ 'screenshot_startup_${DateTime.now().toLocal().toIso8601String()}.png',
+ );
+ });
final int result = await flutter('run', options: <String>[
'--no-android-gradle-daemon',
'--no-publish-port',
@@ -780,7 +791,8 @@
device.deviceId,
if (applicationBinaryPath != null)
'--use-application-binary=$applicationBinaryPath',
- ], canFail: true);
+ ], canFail: true);
+ timer.cancel();
if (result == 0) {
final Map<String, dynamic> data = json.decode(
file('${_testOutputDirectory(testDirectory)}/start_up_info.json').readAsStringSync(),
@@ -788,20 +800,10 @@
results.add(data);
} else {
currentFailures += 1;
- if (hostAgent.dumpDirectory != null) {
- await flutter(
- 'screenshot',
- options: <String>[
- '-d',
- device.deviceId,
- '--out',
- hostAgent.dumpDirectory!
- .childFile('screenshot_startup_failure_$currentFailures.png')
- .path,
- ],
- canFail: true,
- );
- }
+ await _flutterScreenshot(
+ device.deviceId,
+ 'screenshot_startup_failure_$currentFailures.png',
+ );
i -= 1;
if (currentFailures == maxFailures) {
return TaskResult.failure('Application failed to start $maxFailures times');
@@ -827,6 +829,23 @@
]);
});
}
+
+ Future<void> _flutterScreenshot(String deviceId, String screenshotName) async {
+ if (hostAgent.dumpDirectory != null) {
+ await flutter(
+ 'screenshot',
+ options: <String>[
+ '-d',
+ deviceId,
+ '--out',
+ hostAgent.dumpDirectory!
+ .childFile(screenshotName)
+ .path,
+ ],
+ canFail: true,
+ );
+ }
+ }
}
/// A one-off test to verify that devtools starts in profile mode.
diff --git a/dev/devicelab/lib/tasks/web_benchmarks.dart b/dev/devicelab/lib/tasks/web_benchmarks.dart
index de98f4f..051133c 100644
--- a/dev/devicelab/lib/tasks/web_benchmarks.dart
+++ b/dev/devicelab/lib/tasks/web_benchmarks.dart
@@ -20,7 +20,12 @@
const int benchmarkServerPort = 9999;
const int chromeDebugPort = 10000;
-Future<TaskResult> runWebBenchmark({ required bool useCanvasKit }) async {
+typedef WebBenchmarkOptions = ({
+ String webRenderer,
+ bool useWasm,
+});
+
+Future<TaskResult> runWebBenchmark(WebBenchmarkOptions benchmarkOptions) async {
// Reduce logging level. Otherwise, package:webkit_inspection_protocol is way too spammy.
Logger.root.level = Level.INFO;
final String macrobenchmarksDirectory = path.join(flutterDirectory.path, 'dev', 'benchmarks', 'macrobenchmarks');
@@ -28,8 +33,12 @@
await flutter('clean');
await evalFlutter('build', options: <String>[
'web',
+ if (benchmarkOptions.useWasm) ...<String>[
+ '--wasm',
+ '--wasm-opt=debug',
+ ],
'--dart-define=FLUTTER_WEB_ENABLE_PROFILING=true',
- '--web-renderer=${useCanvasKit ? 'canvaskit' : 'html'}',
+ '--web-renderer=${benchmarkOptions.webRenderer}',
'--profile',
'--no-web-resources-cdn',
'-t',
@@ -115,7 +124,7 @@
return Response.internalServerError(body: '$error');
}
}).add(createBuildDirectoryHandler(
- path.join(macrobenchmarksDirectory, 'build', 'web'),
+ path.join(macrobenchmarksDirectory, 'build', benchmarkOptions.useWasm ? 'web_wasm' : 'web'),
));
server = await io.HttpServer.bind('localhost', benchmarkServerPort);
@@ -137,6 +146,7 @@
userDataDirectory: userDataDir,
headless: isUncalibratedSmokeTest,
debugPort: chromeDebugPort,
+ enableWasmGC: benchmarkOptions.useWasm,
);
print('Launching Chrome.');
@@ -149,7 +159,6 @@
);
print('Waiting for the benchmark to report benchmark profile.');
- final String backend = useCanvasKit ? 'canvaskit' : 'html';
final Map<String, dynamic> taskResult = <String, dynamic>{};
final List<String> benchmarkScoreKeys = <String>[];
final List<Map<String, dynamic>> profiles = await profileData.future;
@@ -161,7 +170,7 @@
throw 'Benchmark name is empty';
}
- final String namespace = '$benchmarkName.$backend';
+ final String namespace = '$benchmarkName.${benchmarkOptions.webRenderer}';
final List<String> scoreKeys = List<String>.from(profile['scoreKeys'] as List<dynamic>);
if (scoreKeys.isEmpty) {
throw 'No score keys in benchmark "$benchmarkName"';
diff --git a/dev/devicelab/pubspec.yaml b/dev/devicelab/pubspec.yaml
index b7f17d9..5eb968e 100644
--- a/dev/devicelab/pubspec.yaml
+++ b/dev/devicelab/pubspec.yaml
@@ -12,16 +12,16 @@
http: 0.13.6
logging: 1.2.0
meta: 1.9.1
- metrics_center: 1.0.9
+ metrics_center: 1.0.10
path: 1.8.3
platform: 3.1.0
process: 4.2.4
pubspec_parse: 1.2.3
shelf: 1.4.1
shelf_static: 1.1.2
- stack_trace: 1.11.0
- vm_service: 11.6.0
- web: 0.1.3-beta
+ stack_trace: 1.11.1
+ vm_service: 11.7.2
+ web: 0.1.4-beta
webkit_inspection_protocol: 1.2.0
_discoveryapis_commons: 1.0.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -31,7 +31,7 @@
convert: 3.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
crypto: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
equatable: 2.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- gcloud: 0.8.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ gcloud: 0.8.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
googleapis: 3.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
googleapis_auth: 1.4.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http_parser: 4.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -40,19 +40,20 @@
mime: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
pub_semver: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
- test: 1.24.3
+ test: 1.24.4
- _fe_analyzer_shared: 61.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- analyzer: 5.13.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ _fe_analyzer_shared: 62.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ analyzer: 6.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
coverage: 1.6.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ dart_internal: 0.2.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
frontend_server_client: 3.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
glob: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http_multi_server: 3.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -65,9 +66,9 @@
shelf_web_socket: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_map_stack_trace: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_maps: 0.10.12 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_core: 0.5.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_core: 0.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
-# PUBSPEC CHECKSUM: 968c
+# PUBSPEC CHECKSUM: 1d4a
diff --git a/dev/forbidden_from_release_tests/pubspec.yaml b/dev/forbidden_from_release_tests/pubspec.yaml
index 48beef5..38a767f 100644
--- a/dev/forbidden_from_release_tests/pubspec.yaml
+++ b/dev/forbidden_from_release_tests/pubspec.yaml
@@ -10,10 +10,10 @@
package_config: 2.1.0
path: 1.8.3
process: 4.2.4
- vm_snapshot_analysis: 0.7.2
+ vm_snapshot_analysis: 0.7.6
collection: 1.17.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.9.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
platform: 3.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
-# PUBSPEC CHECKSUM: 5a67
+# PUBSPEC CHECKSUM: 5e6b
diff --git a/dev/integration_tests/abstract_method_smoke_test/android/build.gradle b/dev/integration_tests/abstract_method_smoke_test/android/build.gradle
index 57ace36..a2a8866 100644
--- a/dev/integration_tests/abstract_method_smoke_test/android/build.gradle
+++ b/dev/integration_tests/abstract_method_smoke_test/android/build.gradle
@@ -7,14 +7,14 @@
// See dev/tools/bin/generate_gradle_lockfiles.dart.
buildscript {
- ext.kotlin_version = '1.5.31'
+ ext.kotlin_version = '1.7.10'
repositories {
google()
mavenCentral()
}
dependencies {
- classpath 'com.android.tools.build:gradle:4.1.3'
+ classpath 'com.android.tools.build:gradle:7.3.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
diff --git a/dev/integration_tests/abstract_method_smoke_test/android/buildscript-gradle.lockfile b/dev/integration_tests/abstract_method_smoke_test/android/buildscript-gradle.lockfile
index 2577f0a..eb60580 100644
--- a/dev/integration_tests/abstract_method_smoke_test/android/buildscript-gradle.lockfile
+++ b/dev/integration_tests/abstract_method_smoke_test/android/buildscript-gradle.lockfile
@@ -1,120 +1,152 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
-androidx.databinding:databinding-common:4.1.3=classpath
-androidx.databinding:databinding-compiler-common:4.1.3=classpath
-com.android.databinding:baseLibrary:4.1.3=classpath
-com.android.tools.analytics-library:crash:27.1.3=classpath
-com.android.tools.analytics-library:protos:27.1.3=classpath
-com.android.tools.analytics-library:shared:27.1.3=classpath
-com.android.tools.analytics-library:tracker:27.1.3=classpath
-com.android.tools.build.jetifier:jetifier-core:1.0.0-beta09=classpath
-com.android.tools.build.jetifier:jetifier-processor:1.0.0-beta09=classpath
-com.android.tools.build:aapt2-proto:4.1.3-6503028=classpath
-com.android.tools.build:aaptcompiler:4.1.3=classpath
-com.android.tools.build:apksig:4.1.3=classpath
-com.android.tools.build:apkzlib:4.1.3=classpath
-com.android.tools.build:builder-model:4.1.3=classpath
-com.android.tools.build:builder-test-api:4.1.3=classpath
-com.android.tools.build:builder:4.1.3=classpath
-com.android.tools.build:bundletool:0.14.0=classpath
-com.android.tools.build:gradle-api:4.1.3=classpath
-com.android.tools.build:gradle:4.1.3=classpath
-com.android.tools.build:manifest-merger:27.1.3=classpath
+androidx.databinding:databinding-common:7.3.0=classpath
+androidx.databinding:databinding-compiler-common:7.3.0=classpath
+com.android.databinding:baseLibrary:7.3.0=classpath
+com.android.tools.analytics-library:crash:30.3.0=classpath
+com.android.tools.analytics-library:protos:30.3.0=classpath
+com.android.tools.analytics-library:shared:30.3.0=classpath
+com.android.tools.analytics-library:tracker:30.3.0=classpath
+com.android.tools.build.jetifier:jetifier-core:1.0.0-beta10=classpath
+com.android.tools.build.jetifier:jetifier-processor:1.0.0-beta10=classpath
+com.android.tools.build:aapt2-proto:7.3.0-8691043=classpath
+com.android.tools.build:aaptcompiler:7.3.0=classpath
+com.android.tools.build:apksig:7.3.0=classpath
+com.android.tools.build:apkzlib:7.3.0=classpath
+com.android.tools.build:builder-model:7.3.0=classpath
+com.android.tools.build:builder-test-api:7.3.0=classpath
+com.android.tools.build:builder:7.3.0=classpath
+com.android.tools.build:bundletool:1.9.0=classpath
+com.android.tools.build:gradle-api:7.3.0=classpath
+com.android.tools.build:gradle:7.3.0=classpath
+com.android.tools.build:manifest-merger:30.3.0=classpath
com.android.tools.build:transform-api:2.0.0-deprecated-use-gradle-api=classpath
-com.android.tools.ddms:ddmlib:27.1.3=classpath
-com.android.tools.layoutlib:layoutlib-api:27.1.3=classpath
-com.android.tools.lint:lint-gradle-api:27.1.3=classpath
-com.android.tools.lint:lint-model:27.1.3=classpath
-com.android.tools:annotations:27.1.3=classpath
-com.android.tools:common:27.1.3=classpath
-com.android.tools:dvlib:27.1.3=classpath
-com.android.tools:repository:27.1.3=classpath
-com.android.tools:sdk-common:27.1.3=classpath
-com.android.tools:sdklib:27.1.3=classpath
-com.android:signflinger:4.1.3=classpath
-com.android:zipflinger:4.1.3=classpath
+com.android.tools.ddms:ddmlib:30.3.0=classpath
+com.android.tools.layoutlib:layoutlib-api:30.3.0=classpath
+com.android.tools.lint:lint-model:30.3.0=classpath
+com.android.tools.lint:lint-typedef-remover:30.3.0=classpath
+com.android.tools.utp:android-device-provider-ddmlib-proto:30.3.0=classpath
+com.android.tools.utp:android-device-provider-gradle-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-host-additional-test-output-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-host-coverage-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-host-retention-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-result-listener-gradle-proto:30.3.0=classpath
+com.android.tools:annotations:30.3.0=classpath
+com.android.tools:common:30.3.0=classpath
+com.android.tools:dvlib:30.3.0=classpath
+com.android.tools:repository:30.3.0=classpath
+com.android.tools:sdk-common:30.3.0=classpath
+com.android.tools:sdklib:30.3.0=classpath
+com.android:signflinger:7.3.0=classpath
+com.android:zipflinger:7.3.0=classpath
com.github.gundy:semver4j:0.16.4=classpath
+com.google.android:annotations:4.1.1.4=classpath
+com.google.api.grpc:proto-google-common-protos:2.0.1=classpath
com.google.auto.value:auto-value-annotations:1.6.2=classpath
com.google.code.findbugs:jsr305:3.0.2=classpath
-com.google.code.gson:gson:2.8.6=classpath
+com.google.code.gson:gson:2.8.9=classpath
com.google.crypto.tink:tink:1.3.0-rc2=classpath
-com.google.errorprone:error_prone_annotations:2.3.4=classpath
+com.google.dagger:dagger:2.28.3=classpath
+com.google.errorprone:error_prone_annotations:2.4.0=classpath
com.google.flatbuffers:flatbuffers-java:1.12.0=classpath
com.google.guava:failureaccess:1.0.1=classpath
-com.google.guava:guava:29.0-jre=classpath
+com.google.guava:guava:30.1-jre=classpath
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=classpath
com.google.j2objc:j2objc-annotations:1.3=classpath
com.google.jimfs:jimfs:1.1=classpath
-com.google.protobuf:protobuf-java-util:3.10.0=classpath
-com.google.protobuf:protobuf-java:3.10.0=classpath
-com.google.test.platform:core-proto:0.0.2-dev=classpath
+com.google.protobuf:protobuf-java-util:3.17.2=classpath
+com.google.protobuf:protobuf-java:3.17.2=classpath
+com.google.testing.platform:core-proto:0.0.8-alpha07=classpath
com.googlecode.json-simple:json-simple:1.1=classpath
com.googlecode.juniversalchardet:juniversalchardet:1.0.3=classpath
com.squareup:javapoet:1.10.0=classpath
com.squareup:javawriter:2.5.0=classpath
com.sun.activation:javax.activation:1.2.0=classpath
-com.sun.istack:istack-commons-runtime:3.0.7=classpath
-com.sun.xml.fastinfoset:FastInfoset:1.2.15=classpath
-commons-codec:commons-codec:1.10=classpath
+com.sun.istack:istack-commons-runtime:3.0.8=classpath
+com.sun.xml.fastinfoset:FastInfoset:1.2.16=classpath
+commons-codec:commons-codec:1.11=classpath
commons-io:commons-io:2.4=classpath
commons-logging:commons-logging:1.2=classpath
de.undercouch:gradle-download-task:4.1.1=classpath
-it.unimi.dsi:fastutil:7.2.0=classpath
-javax.activation:javax.activation-api:1.2.0=classpath
+io.grpc:grpc-api:1.39.0=classpath
+io.grpc:grpc-context:1.39.0=classpath
+io.grpc:grpc-core:1.39.0=classpath
+io.grpc:grpc-netty:1.39.0=classpath
+io.grpc:grpc-protobuf-lite:1.39.0=classpath
+io.grpc:grpc-protobuf:1.39.0=classpath
+io.grpc:grpc-stub:1.39.0=classpath
+io.netty:netty-buffer:4.1.52.Final=classpath
+io.netty:netty-codec-http2:4.1.52.Final=classpath
+io.netty:netty-codec-http:4.1.52.Final=classpath
+io.netty:netty-codec-socks:4.1.52.Final=classpath
+io.netty:netty-codec:4.1.52.Final=classpath
+io.netty:netty-common:4.1.52.Final=classpath
+io.netty:netty-handler-proxy:4.1.52.Final=classpath
+io.netty:netty-handler:4.1.52.Final=classpath
+io.netty:netty-resolver:4.1.52.Final=classpath
+io.netty:netty-transport:4.1.52.Final=classpath
+io.perfmark:perfmark-api:0.23.0=classpath
+it.unimi.dsi:fastutil:8.4.0=classpath
+jakarta.activation:jakarta.activation-api:1.2.1=classpath
+jakarta.xml.bind:jakarta.xml.bind-api:2.3.2=classpath
+javax.annotation:javax.annotation-api:1.3.2=classpath
javax.inject:javax.inject:1=classpath
-javax.xml.bind:jaxb-api:2.3.1=classpath
+net.java.dev.jna:jna-platform:5.6.0=classpath
+net.java.dev.jna:jna:5.6.0=classpath
net.sf.jopt-simple:jopt-simple:4.9=classpath
net.sf.kxml:kxml2:2.3.0=classpath
-net.sf.proguard:proguard-base:6.0.3=classpath
-net.sf.proguard:proguard-gradle:6.0.3=classpath
-org.antlr:antlr4:4.5.3=classpath
-org.apache.commons:commons-compress:1.12=classpath
-org.apache.httpcomponents:httpclient:4.5.6=classpath
-org.apache.httpcomponents:httpcore:4.4.10=classpath
+org.apache.commons:commons-compress:1.20=classpath
+org.apache.httpcomponents:httpclient:4.5.13=classpath
+org.apache.httpcomponents:httpcore:4.4.13=classpath
org.apache.httpcomponents:httpmime:4.5.6=classpath
-org.bouncycastle:bcpkix-jdk15on:1.56=classpath
-org.bouncycastle:bcprov-jdk15on:1.56=classpath
-org.checkerframework:checker-qual:2.11.1=classpath
-org.glassfish.jaxb:jaxb-runtime:2.3.1=classpath
-org.glassfish.jaxb:txw2:2.3.1=classpath
+org.bitbucket.b_c:jose4j:0.7.0=classpath
+org.bouncycastle:bcpkix-jdk15on:1.67=classpath
+org.bouncycastle:bcprov-jdk15on:1.67=classpath
+org.checkerframework:checker-qual:3.5.0=classpath
+org.codehaus.mojo:animal-sniffer-annotations:1.19=classpath
+org.glassfish.jaxb:jaxb-runtime:2.3.2=classpath
+org.glassfish.jaxb:txw2:2.3.2=classpath
org.jdom:jdom2:2.0.6=classpath
-org.jetbrains.intellij.deps:trove4j:1.0.20181211=classpath
-org.jetbrains.kotlin:kotlin-android-extensions:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-annotation-processing-gradle:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-build-common:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-compiler-embeddable:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-compiler-runner:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-daemon-client:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-daemon-embeddable:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-native-utils:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-project-model:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-reflect:1.3.72=classpath
-org.jetbrains.kotlin:kotlin-scripting-common:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-scripting-jvm:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-stdlib-common:1.3.72=classpath
-org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.72=classpath
-org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.72=classpath
-org.jetbrains.kotlin:kotlin-stdlib:1.3.72=classpath
-org.jetbrains.kotlin:kotlin-tooling-metadata:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-util-io:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-util-klib:1.5.31=classpath
+org.jetbrains.intellij.deps:trove4j:1.0.20200330=classpath
+org.jetbrains.kotlin:kotlin-android-extensions:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-annotation-processing-gradle:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-build-common:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-compiler-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-compiler-runner:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-daemon-client:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-daemon-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin-idea:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-native-utils:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-project-model:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-reflect:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-scripting-common:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-scripting-jvm:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-stdlib-common:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-stdlib:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-tooling-core:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-tooling-metadata:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-util-io:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-util-klib:1.7.10=classpath
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.0=classpath
-org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0=classpath
-org.jetbrains.trove4j:trove4j:20160824=classpath
org.jetbrains:annotations:13.0=classpath
org.json:json:20180813=classpath
-org.jvnet.staxex:stax-ex:1.8=classpath
-org.ow2.asm:asm-analysis:7.0=classpath
-org.ow2.asm:asm-commons:7.0=classpath
-org.ow2.asm:asm-tree:7.0=classpath
-org.ow2.asm:asm-util:7.0=classpath
-org.ow2.asm:asm:7.0=classpath
-org.tensorflow:tensorflow-lite-metadata:0.1.0-rc1=classpath
+org.jvnet.staxex:stax-ex:1.8.1=classpath
+org.ow2.asm:asm-analysis:9.1=classpath
+org.ow2.asm:asm-commons:9.1=classpath
+org.ow2.asm:asm-tree:9.1=classpath
+org.ow2.asm:asm-util:9.1=classpath
+org.ow2.asm:asm:9.1=classpath
+org.slf4j:slf4j-api:1.7.30=classpath
+org.tensorflow:tensorflow-lite-metadata:0.1.0-rc2=classpath
+xerces:xercesImpl:2.12.0=classpath
+xml-apis:xml-apis:1.4.01=classpath
empty=
diff --git a/dev/integration_tests/abstract_method_smoke_test/android/gradle/wrapper/gradle-wrapper.properties b/dev/integration_tests/abstract_method_smoke_test/android/gradle/wrapper/gradle-wrapper.properties
index 3c9d085..cb24abd 100644
--- a/dev/integration_tests/abstract_method_smoke_test/android/gradle/wrapper/gradle-wrapper.properties
+++ b/dev/integration_tests/abstract_method_smoke_test/android/gradle/wrapper/gradle-wrapper.properties
@@ -2,4 +2,4 @@
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip
diff --git a/dev/integration_tests/abstract_method_smoke_test/android/project-app.lockfile b/dev/integration_tests/abstract_method_smoke_test/android/project-app.lockfile
index c573760..5e0f607 100644
--- a/dev/integration_tests/abstract_method_smoke_test/android/project-app.lockfile
+++ b/dev/integration_tests/abstract_method_smoke_test/android/project-app.lockfile
@@ -21,8 +21,8 @@
androidx.tracing:tracing:1.0.0=debugAndroidTestCompileClasspath,debugApiDependenciesMetadata,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileApiDependenciesMetadata,profileCompileClasspath,profileImplementationDependenciesMetadata,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseApiDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
androidx.versionedparcelable:versionedparcelable:1.1.1=debugAndroidTestCompileClasspath,debugApiDependenciesMetadata,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileApiDependenciesMetadata,profileCompileClasspath,profileImplementationDependenciesMetadata,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseApiDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
androidx.viewpager:viewpager:1.0.0=debugAndroidTestCompileClasspath,debugApiDependenciesMetadata,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileApiDependenciesMetadata,profileCompileClasspath,profileImplementationDependenciesMetadata,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseApiDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
-androidx.window:window-java:1.0.0-beta03=debugAndroidTestCompileClasspath,debugApiDependenciesMetadata,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileApiDependenciesMetadata,profileCompileClasspath,profileImplementationDependenciesMetadata,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseApiDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
-androidx.window:window:1.0.0-beta03=debugAndroidTestCompileClasspath,debugApiDependenciesMetadata,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileApiDependenciesMetadata,profileCompileClasspath,profileImplementationDependenciesMetadata,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseApiDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.window:window-java:1.0.0-beta04=debugAndroidTestCompileClasspath,debugApiDependenciesMetadata,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileApiDependenciesMetadata,profileCompileClasspath,profileImplementationDependenciesMetadata,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseApiDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.window:window:1.0.0-beta04=debugAndroidTestCompileClasspath,debugApiDependenciesMetadata,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileApiDependenciesMetadata,profileCompileClasspath,profileImplementationDependenciesMetadata,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseApiDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
com.android.tools.analytics-library:protos:27.1.3=lintClassPath
com.android.tools.analytics-library:shared:27.1.3=lintClassPath
com.android.tools.analytics-library:tracker:27.1.3=lintClassPath
@@ -74,6 +74,7 @@
javax.activation:javax.activation-api:1.2.0=lintClassPath
javax.inject:javax.inject:1=lintClassPath
javax.xml.bind:jaxb-api:2.3.1=lintClassPath
+net.java.dev.jna:jna:5.6.0=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
net.sf.jopt-simple:jopt-simple:4.9=lintClassPath
net.sf.kxml:kxml2:2.3.0=lintClassPath
org.apache.commons:commons-compress:1.12=lintClassPath
@@ -87,22 +88,29 @@
org.codehaus.mojo:animal-sniffer-annotations:1.18=lintClassPath
org.glassfish.jaxb:jaxb-runtime:2.3.1=lintClassPath
org.glassfish.jaxb:txw2:2.3.1=lintClassPath
-org.jetbrains.intellij.deps:trove4j:1.0.20181211=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
-org.jetbrains.kotlin:kotlin-compiler-embeddable:1.5.31=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
-org.jetbrains.kotlin:kotlin-daemon-embeddable:1.5.31=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
-org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:1.5.31=kotlinKlibCommonizerClasspath
+org.jacoco:org.jacoco.agent:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.ant:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.core:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.report:0.8.7=androidJacocoAnt
+org.jetbrains.intellij.deps:trove4j:1.0.20200330=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
+org.jetbrains.kotlin:kotlin-compiler-embeddable:1.7.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
+org.jetbrains.kotlin:kotlin-daemon-embeddable:1.7.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
+org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:1.7.10=kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-reflect:1.3.72=lintClassPath
-org.jetbrains.kotlin:kotlin-reflect:1.5.31=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
-org.jetbrains.kotlin:kotlin-script-runtime:1.5.31=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
+org.jetbrains.kotlin:kotlin-reflect:1.7.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
+org.jetbrains.kotlin:kotlin-script-runtime:1.7.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-stdlib-common:1.3.72=lintClassPath
-org.jetbrains.kotlin:kotlin-stdlib-common:1.5.31=debugAndroidTestCompileClasspath,debugApiDependenciesMetadata,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,profileApiDependenciesMetadata,profileCompileClasspath,profileImplementationDependenciesMetadata,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseApiDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlin:kotlin-stdlib-common:1.5.31=debugApiDependenciesMetadata,profileApiDependenciesMetadata,releaseApiDependenciesMetadata
+org.jetbrains.kotlin:kotlin-stdlib-common:1.7.10=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,profileCompileClasspath,profileImplementationDependenciesMetadata,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.72=lintClassPath
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.5.30=debugApiDependenciesMetadata,profileApiDependenciesMetadata,releaseApiDependenciesMetadata
-org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.5.31=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,profileCompileClasspath,profileImplementationDependenciesMetadata,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.10=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,profileCompileClasspath,profileImplementationDependenciesMetadata,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.72=lintClassPath
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.30=debugAndroidTestCompileClasspath,debugApiDependenciesMetadata,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileApiDependenciesMetadata,profileCompileClasspath,profileImplementationDependenciesMetadata,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseApiDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.jetbrains.kotlin:kotlin-stdlib:1.3.72=lintClassPath
-org.jetbrains.kotlin:kotlin-stdlib:1.5.31=debugAndroidTestCompileClasspath,debugApiDependenciesMetadata,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,profileApiDependenciesMetadata,profileCompileClasspath,profileImplementationDependenciesMetadata,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseApiDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlin:kotlin-stdlib:1.5.31=debugApiDependenciesMetadata,profileApiDependenciesMetadata,releaseApiDependenciesMetadata
+org.jetbrains.kotlin:kotlin-stdlib:1.7.10=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,profileCompileClasspath,profileImplementationDependenciesMetadata,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlinx:atomicfu:0.16.3=debugApiDependenciesMetadata,debugImplementationDependenciesMetadata,profileApiDependenciesMetadata,profileImplementationDependenciesMetadata,releaseApiDependenciesMetadata,releaseImplementationDependenciesMetadata
org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2=debugAndroidTestCompileClasspath,debugApiDependenciesMetadata,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileApiDependenciesMetadata,profileCompileClasspath,profileImplementationDependenciesMetadata,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseApiDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.2=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2=debugAndroidTestCompileClasspath,debugApiDependenciesMetadata,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileApiDependenciesMetadata,profileCompileClasspath,profileImplementationDependenciesMetadata,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseApiDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
@@ -110,8 +118,12 @@
org.jetbrains:annotations:13.0=debugAndroidTestCompileClasspath,debugApiDependenciesMetadata,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,lintClassPath,profileApiDependenciesMetadata,profileCompileClasspath,profileImplementationDependenciesMetadata,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseApiDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.jvnet.staxex:stax-ex:1.8=lintClassPath
org.ow2.asm:asm-analysis:7.0=lintClassPath
+org.ow2.asm:asm-analysis:9.1=androidJacocoAnt
org.ow2.asm:asm-commons:7.0=lintClassPath
+org.ow2.asm:asm-commons:9.1=androidJacocoAnt
org.ow2.asm:asm-tree:7.0=lintClassPath
+org.ow2.asm:asm-tree:9.1=androidJacocoAnt
org.ow2.asm:asm-util:7.0=lintClassPath
org.ow2.asm:asm:7.0=lintClassPath
-empty=androidApis,androidTestApiDependenciesMetadata,androidTestCompileOnlyDependenciesMetadata,androidTestDebugApiDependenciesMetadata,androidTestDebugCompileOnlyDependenciesMetadata,androidTestDebugImplementationDependenciesMetadata,androidTestDebugIntransitiveDependenciesMetadata,androidTestDebugRuntimeOnlyDependenciesMetadata,androidTestImplementationDependenciesMetadata,androidTestIntransitiveDependenciesMetadata,androidTestProfileApiDependenciesMetadata,androidTestProfileCompileOnlyDependenciesMetadata,androidTestProfileImplementationDependenciesMetadata,androidTestProfileIntransitiveDependenciesMetadata,androidTestProfileRuntimeOnlyDependenciesMetadata,androidTestReleaseApiDependenciesMetadata,androidTestReleaseCompileOnlyDependenciesMetadata,androidTestReleaseImplementationDependenciesMetadata,androidTestReleaseIntransitiveDependenciesMetadata,androidTestReleaseRuntimeOnlyDependenciesMetadata,androidTestRuntimeOnlyDependenciesMetadata,androidTestUtil,apiDependenciesMetadata,compile,compileOnlyDependenciesMetadata,coreLibraryDesugaring,debugAndroidTestAnnotationProcessorClasspath,debugAndroidTestApiDependenciesMetadata,debugAndroidTestCompileOnlyDependenciesMetadata,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestIntransitiveDependenciesMetadata,debugAndroidTestRuntimeClasspath,debugAndroidTestRuntimeOnlyDependenciesMetadata,debugAnnotationProcessorClasspath,debugCompile,debugCompileOnly,debugCompileOnlyDependenciesMetadata,debugIntransitiveDependenciesMetadata,debugReverseMetadataValues,debugRuntimeOnlyDependenciesMetadata,debugUnitTestAnnotationProcessorClasspath,debugUnitTestApiDependenciesMetadata,debugUnitTestCompileOnlyDependenciesMetadata,debugUnitTestImplementationDependenciesMetadata,debugUnitTestIntransitiveDependenciesMetadata,debugUnitTestRuntimeOnlyDependenciesMetadata,debugWearBundling,intransitiveDependenciesMetadata,kotlinCompilerPluginClasspath,kotlinCompilerPluginClasspathDebug,kotlinCompilerPluginClasspathDebugAndroidTest,kotlinCompilerPluginClasspathDebugUnitTest,kotlinCompilerPluginClasspathProfile,kotlinCompilerPluginClasspathProfileUnitTest,kotlinCompilerPluginClasspathRelease,kotlinCompilerPluginClasspathReleaseUnitTest,kotlinNativeCompilerPluginClasspath,lintChecks,lintPublish,profileAnnotationProcessorClasspath,profileCompile,profileCompileOnly,profileCompileOnlyDependenciesMetadata,profileIntransitiveDependenciesMetadata,profileReverseMetadataValues,profileRuntimeOnlyDependenciesMetadata,profileUnitTestAnnotationProcessorClasspath,profileUnitTestApiDependenciesMetadata,profileUnitTestCompileOnlyDependenciesMetadata,profileUnitTestImplementationDependenciesMetadata,profileUnitTestIntransitiveDependenciesMetadata,profileUnitTestRuntimeOnlyDependenciesMetadata,profileWearBundling,releaseAnnotationProcessorClasspath,releaseCompile,releaseCompileOnly,releaseCompileOnlyDependenciesMetadata,releaseIntransitiveDependenciesMetadata,releaseReverseMetadataValues,releaseRuntimeOnlyDependenciesMetadata,releaseUnitTestAnnotationProcessorClasspath,releaseUnitTestApiDependenciesMetadata,releaseUnitTestCompileOnlyDependenciesMetadata,releaseUnitTestImplementationDependenciesMetadata,releaseUnitTestIntransitiveDependenciesMetadata,releaseUnitTestRuntimeOnlyDependenciesMetadata,releaseWearBundling,runtimeOnlyDependenciesMetadata,testApiDependenciesMetadata,testCompile,testCompileOnlyDependenciesMetadata,testDebugApiDependenciesMetadata,testDebugCompileOnlyDependenciesMetadata,testDebugImplementationDependenciesMetadata,testDebugIntransitiveDependenciesMetadata,testDebugRuntimeOnlyDependenciesMetadata,testImplementationDependenciesMetadata,testIntransitiveDependenciesMetadata,testProfileApiDependenciesMetadata,testProfileCompileOnlyDependenciesMetadata,testProfileImplementationDependenciesMetadata,testProfileIntransitiveDependenciesMetadata,testProfileRuntimeOnlyDependenciesMetadata,testReleaseApiDependenciesMetadata,testReleaseCompileOnlyDependenciesMetadata,testReleaseImplementationDependenciesMetadata,testReleaseIntransitiveDependenciesMetadata,testReleaseRuntimeOnlyDependenciesMetadata,testRuntimeOnlyDependenciesMetadata
+org.ow2.asm:asm:9.1=androidJacocoAnt
+empty=androidApis,androidJdkImage,androidTestApiDependenciesMetadata,androidTestCompileOnlyDependenciesMetadata,androidTestDebugApiDependenciesMetadata,androidTestDebugCompileOnlyDependenciesMetadata,androidTestDebugImplementationDependenciesMetadata,androidTestDebugIntransitiveDependenciesMetadata,androidTestDebugRuntimeOnlyDependenciesMetadata,androidTestImplementationDependenciesMetadata,androidTestIntransitiveDependenciesMetadata,androidTestProfileApiDependenciesMetadata,androidTestProfileCompileOnlyDependenciesMetadata,androidTestProfileImplementationDependenciesMetadata,androidTestProfileIntransitiveDependenciesMetadata,androidTestProfileRuntimeOnlyDependenciesMetadata,androidTestReleaseApiDependenciesMetadata,androidTestReleaseCompileOnlyDependenciesMetadata,androidTestReleaseImplementationDependenciesMetadata,androidTestReleaseIntransitiveDependenciesMetadata,androidTestReleaseRuntimeOnlyDependenciesMetadata,androidTestRuntimeOnlyDependenciesMetadata,androidTestUtil,apiDependenciesMetadata,compile,compileOnlyDependenciesMetadata,coreLibraryDesugaring,debugAndroidTestAnnotationProcessorClasspath,debugAndroidTestApiDependenciesMetadata,debugAndroidTestCompileOnlyDependenciesMetadata,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestIntransitiveDependenciesMetadata,debugAndroidTestRuntimeClasspath,debugAndroidTestRuntimeOnlyDependenciesMetadata,debugAnnotationProcessorClasspath,debugCompile,debugCompileOnly,debugCompileOnlyDependenciesMetadata,debugIntransitiveDependenciesMetadata,debugReverseMetadataValues,debugRuntimeOnlyDependenciesMetadata,debugUnitTestAnnotationProcessorClasspath,debugUnitTestApiDependenciesMetadata,debugUnitTestCompileOnlyDependenciesMetadata,debugUnitTestImplementationDependenciesMetadata,debugUnitTestIntransitiveDependenciesMetadata,debugUnitTestRuntimeOnlyDependenciesMetadata,debugWearBundling,intransitiveDependenciesMetadata,kotlinCompilerPluginClasspath,kotlinCompilerPluginClasspathDebug,kotlinCompilerPluginClasspathDebugAndroidTest,kotlinCompilerPluginClasspathDebugUnitTest,kotlinCompilerPluginClasspathProfile,kotlinCompilerPluginClasspathProfileUnitTest,kotlinCompilerPluginClasspathRelease,kotlinCompilerPluginClasspathReleaseUnitTest,kotlinNativeCompilerPluginClasspath,lintChecks,lintPublish,profileAnnotationProcessorClasspath,profileCompile,profileCompileOnly,profileCompileOnlyDependenciesMetadata,profileIntransitiveDependenciesMetadata,profileReverseMetadataValues,profileRuntimeOnlyDependenciesMetadata,profileUnitTestAnnotationProcessorClasspath,profileUnitTestApiDependenciesMetadata,profileUnitTestCompileOnlyDependenciesMetadata,profileUnitTestImplementationDependenciesMetadata,profileUnitTestIntransitiveDependenciesMetadata,profileUnitTestRuntimeOnlyDependenciesMetadata,profileWearBundling,releaseAnnotationProcessorClasspath,releaseCompile,releaseCompileOnly,releaseCompileOnlyDependenciesMetadata,releaseIntransitiveDependenciesMetadata,releaseReverseMetadataValues,releaseRuntimeOnlyDependenciesMetadata,releaseUnitTestAnnotationProcessorClasspath,releaseUnitTestApiDependenciesMetadata,releaseUnitTestCompileOnlyDependenciesMetadata,releaseUnitTestImplementationDependenciesMetadata,releaseUnitTestIntransitiveDependenciesMetadata,releaseUnitTestRuntimeOnlyDependenciesMetadata,releaseWearBundling,runtimeOnlyDependenciesMetadata,testApiDependenciesMetadata,testCompile,testCompileOnlyDependenciesMetadata,testDebugApiDependenciesMetadata,testDebugCompileOnlyDependenciesMetadata,testDebugImplementationDependenciesMetadata,testDebugIntransitiveDependenciesMetadata,testDebugRuntimeOnlyDependenciesMetadata,testFixturesApiDependenciesMetadata,testFixturesCompileOnlyDependenciesMetadata,testFixturesDebugApiDependenciesMetadata,testFixturesDebugCompileOnlyDependenciesMetadata,testFixturesDebugImplementationDependenciesMetadata,testFixturesDebugIntransitiveDependenciesMetadata,testFixturesDebugRuntimeOnlyDependenciesMetadata,testFixturesImplementationDependenciesMetadata,testFixturesIntransitiveDependenciesMetadata,testFixturesProfileApiDependenciesMetadata,testFixturesProfileCompileOnlyDependenciesMetadata,testFixturesProfileImplementationDependenciesMetadata,testFixturesProfileIntransitiveDependenciesMetadata,testFixturesProfileRuntimeOnlyDependenciesMetadata,testFixturesReleaseApiDependenciesMetadata,testFixturesReleaseCompileOnlyDependenciesMetadata,testFixturesReleaseImplementationDependenciesMetadata,testFixturesReleaseIntransitiveDependenciesMetadata,testFixturesReleaseRuntimeOnlyDependenciesMetadata,testFixturesRuntimeOnlyDependenciesMetadata,testImplementationDependenciesMetadata,testIntransitiveDependenciesMetadata,testProfileApiDependenciesMetadata,testProfileCompileOnlyDependenciesMetadata,testProfileImplementationDependenciesMetadata,testProfileIntransitiveDependenciesMetadata,testProfileRuntimeOnlyDependenciesMetadata,testReleaseApiDependenciesMetadata,testReleaseCompileOnlyDependenciesMetadata,testReleaseImplementationDependenciesMetadata,testReleaseIntransitiveDependenciesMetadata,testReleaseRuntimeOnlyDependenciesMetadata,testRuntimeOnlyDependenciesMetadata
diff --git a/dev/integration_tests/abstract_method_smoke_test/android/settings.gradle b/dev/integration_tests/abstract_method_smoke_test/android/settings.gradle
index 03ae72d..a020595 100644
--- a/dev/integration_tests/abstract_method_smoke_test/android/settings.gradle
+++ b/dev/integration_tests/abstract_method_smoke_test/android/settings.gradle
@@ -8,8 +8,6 @@
include ':app'
-enableFeaturePreview('ONE_LOCKFILE_PER_PROJECT')
-
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()
diff --git a/dev/integration_tests/abstract_method_smoke_test/pubspec.yaml b/dev/integration_tests/abstract_method_smoke_test/pubspec.yaml
index 9387869..737b9e6 100644
--- a/dev/integration_tests/abstract_method_smoke_test/pubspec.yaml
+++ b/dev/integration_tests/abstract_method_smoke_test/pubspec.yaml
@@ -12,12 +12,12 @@
characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
collection: 1.17.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.9.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
flutter:
uses-material-design: true
-# PUBSPEC CHECKSUM: 3e9c
+# PUBSPEC CHECKSUM: a9c0
diff --git a/dev/integration_tests/android_embedding_v2_smoke_test/android/build.gradle b/dev/integration_tests/android_embedding_v2_smoke_test/android/build.gradle
index 57ace36..a2a8866 100644
--- a/dev/integration_tests/android_embedding_v2_smoke_test/android/build.gradle
+++ b/dev/integration_tests/android_embedding_v2_smoke_test/android/build.gradle
@@ -7,14 +7,14 @@
// See dev/tools/bin/generate_gradle_lockfiles.dart.
buildscript {
- ext.kotlin_version = '1.5.31'
+ ext.kotlin_version = '1.7.10'
repositories {
google()
mavenCentral()
}
dependencies {
- classpath 'com.android.tools.build:gradle:4.1.3'
+ classpath 'com.android.tools.build:gradle:7.3.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
diff --git a/dev/integration_tests/android_embedding_v2_smoke_test/android/buildscript-gradle.lockfile b/dev/integration_tests/android_embedding_v2_smoke_test/android/buildscript-gradle.lockfile
index 2577f0a..eb60580 100644
--- a/dev/integration_tests/android_embedding_v2_smoke_test/android/buildscript-gradle.lockfile
+++ b/dev/integration_tests/android_embedding_v2_smoke_test/android/buildscript-gradle.lockfile
@@ -1,120 +1,152 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
-androidx.databinding:databinding-common:4.1.3=classpath
-androidx.databinding:databinding-compiler-common:4.1.3=classpath
-com.android.databinding:baseLibrary:4.1.3=classpath
-com.android.tools.analytics-library:crash:27.1.3=classpath
-com.android.tools.analytics-library:protos:27.1.3=classpath
-com.android.tools.analytics-library:shared:27.1.3=classpath
-com.android.tools.analytics-library:tracker:27.1.3=classpath
-com.android.tools.build.jetifier:jetifier-core:1.0.0-beta09=classpath
-com.android.tools.build.jetifier:jetifier-processor:1.0.0-beta09=classpath
-com.android.tools.build:aapt2-proto:4.1.3-6503028=classpath
-com.android.tools.build:aaptcompiler:4.1.3=classpath
-com.android.tools.build:apksig:4.1.3=classpath
-com.android.tools.build:apkzlib:4.1.3=classpath
-com.android.tools.build:builder-model:4.1.3=classpath
-com.android.tools.build:builder-test-api:4.1.3=classpath
-com.android.tools.build:builder:4.1.3=classpath
-com.android.tools.build:bundletool:0.14.0=classpath
-com.android.tools.build:gradle-api:4.1.3=classpath
-com.android.tools.build:gradle:4.1.3=classpath
-com.android.tools.build:manifest-merger:27.1.3=classpath
+androidx.databinding:databinding-common:7.3.0=classpath
+androidx.databinding:databinding-compiler-common:7.3.0=classpath
+com.android.databinding:baseLibrary:7.3.0=classpath
+com.android.tools.analytics-library:crash:30.3.0=classpath
+com.android.tools.analytics-library:protos:30.3.0=classpath
+com.android.tools.analytics-library:shared:30.3.0=classpath
+com.android.tools.analytics-library:tracker:30.3.0=classpath
+com.android.tools.build.jetifier:jetifier-core:1.0.0-beta10=classpath
+com.android.tools.build.jetifier:jetifier-processor:1.0.0-beta10=classpath
+com.android.tools.build:aapt2-proto:7.3.0-8691043=classpath
+com.android.tools.build:aaptcompiler:7.3.0=classpath
+com.android.tools.build:apksig:7.3.0=classpath
+com.android.tools.build:apkzlib:7.3.0=classpath
+com.android.tools.build:builder-model:7.3.0=classpath
+com.android.tools.build:builder-test-api:7.3.0=classpath
+com.android.tools.build:builder:7.3.0=classpath
+com.android.tools.build:bundletool:1.9.0=classpath
+com.android.tools.build:gradle-api:7.3.0=classpath
+com.android.tools.build:gradle:7.3.0=classpath
+com.android.tools.build:manifest-merger:30.3.0=classpath
com.android.tools.build:transform-api:2.0.0-deprecated-use-gradle-api=classpath
-com.android.tools.ddms:ddmlib:27.1.3=classpath
-com.android.tools.layoutlib:layoutlib-api:27.1.3=classpath
-com.android.tools.lint:lint-gradle-api:27.1.3=classpath
-com.android.tools.lint:lint-model:27.1.3=classpath
-com.android.tools:annotations:27.1.3=classpath
-com.android.tools:common:27.1.3=classpath
-com.android.tools:dvlib:27.1.3=classpath
-com.android.tools:repository:27.1.3=classpath
-com.android.tools:sdk-common:27.1.3=classpath
-com.android.tools:sdklib:27.1.3=classpath
-com.android:signflinger:4.1.3=classpath
-com.android:zipflinger:4.1.3=classpath
+com.android.tools.ddms:ddmlib:30.3.0=classpath
+com.android.tools.layoutlib:layoutlib-api:30.3.0=classpath
+com.android.tools.lint:lint-model:30.3.0=classpath
+com.android.tools.lint:lint-typedef-remover:30.3.0=classpath
+com.android.tools.utp:android-device-provider-ddmlib-proto:30.3.0=classpath
+com.android.tools.utp:android-device-provider-gradle-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-host-additional-test-output-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-host-coverage-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-host-retention-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-result-listener-gradle-proto:30.3.0=classpath
+com.android.tools:annotations:30.3.0=classpath
+com.android.tools:common:30.3.0=classpath
+com.android.tools:dvlib:30.3.0=classpath
+com.android.tools:repository:30.3.0=classpath
+com.android.tools:sdk-common:30.3.0=classpath
+com.android.tools:sdklib:30.3.0=classpath
+com.android:signflinger:7.3.0=classpath
+com.android:zipflinger:7.3.0=classpath
com.github.gundy:semver4j:0.16.4=classpath
+com.google.android:annotations:4.1.1.4=classpath
+com.google.api.grpc:proto-google-common-protos:2.0.1=classpath
com.google.auto.value:auto-value-annotations:1.6.2=classpath
com.google.code.findbugs:jsr305:3.0.2=classpath
-com.google.code.gson:gson:2.8.6=classpath
+com.google.code.gson:gson:2.8.9=classpath
com.google.crypto.tink:tink:1.3.0-rc2=classpath
-com.google.errorprone:error_prone_annotations:2.3.4=classpath
+com.google.dagger:dagger:2.28.3=classpath
+com.google.errorprone:error_prone_annotations:2.4.0=classpath
com.google.flatbuffers:flatbuffers-java:1.12.0=classpath
com.google.guava:failureaccess:1.0.1=classpath
-com.google.guava:guava:29.0-jre=classpath
+com.google.guava:guava:30.1-jre=classpath
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=classpath
com.google.j2objc:j2objc-annotations:1.3=classpath
com.google.jimfs:jimfs:1.1=classpath
-com.google.protobuf:protobuf-java-util:3.10.0=classpath
-com.google.protobuf:protobuf-java:3.10.0=classpath
-com.google.test.platform:core-proto:0.0.2-dev=classpath
+com.google.protobuf:protobuf-java-util:3.17.2=classpath
+com.google.protobuf:protobuf-java:3.17.2=classpath
+com.google.testing.platform:core-proto:0.0.8-alpha07=classpath
com.googlecode.json-simple:json-simple:1.1=classpath
com.googlecode.juniversalchardet:juniversalchardet:1.0.3=classpath
com.squareup:javapoet:1.10.0=classpath
com.squareup:javawriter:2.5.0=classpath
com.sun.activation:javax.activation:1.2.0=classpath
-com.sun.istack:istack-commons-runtime:3.0.7=classpath
-com.sun.xml.fastinfoset:FastInfoset:1.2.15=classpath
-commons-codec:commons-codec:1.10=classpath
+com.sun.istack:istack-commons-runtime:3.0.8=classpath
+com.sun.xml.fastinfoset:FastInfoset:1.2.16=classpath
+commons-codec:commons-codec:1.11=classpath
commons-io:commons-io:2.4=classpath
commons-logging:commons-logging:1.2=classpath
de.undercouch:gradle-download-task:4.1.1=classpath
-it.unimi.dsi:fastutil:7.2.0=classpath
-javax.activation:javax.activation-api:1.2.0=classpath
+io.grpc:grpc-api:1.39.0=classpath
+io.grpc:grpc-context:1.39.0=classpath
+io.grpc:grpc-core:1.39.0=classpath
+io.grpc:grpc-netty:1.39.0=classpath
+io.grpc:grpc-protobuf-lite:1.39.0=classpath
+io.grpc:grpc-protobuf:1.39.0=classpath
+io.grpc:grpc-stub:1.39.0=classpath
+io.netty:netty-buffer:4.1.52.Final=classpath
+io.netty:netty-codec-http2:4.1.52.Final=classpath
+io.netty:netty-codec-http:4.1.52.Final=classpath
+io.netty:netty-codec-socks:4.1.52.Final=classpath
+io.netty:netty-codec:4.1.52.Final=classpath
+io.netty:netty-common:4.1.52.Final=classpath
+io.netty:netty-handler-proxy:4.1.52.Final=classpath
+io.netty:netty-handler:4.1.52.Final=classpath
+io.netty:netty-resolver:4.1.52.Final=classpath
+io.netty:netty-transport:4.1.52.Final=classpath
+io.perfmark:perfmark-api:0.23.0=classpath
+it.unimi.dsi:fastutil:8.4.0=classpath
+jakarta.activation:jakarta.activation-api:1.2.1=classpath
+jakarta.xml.bind:jakarta.xml.bind-api:2.3.2=classpath
+javax.annotation:javax.annotation-api:1.3.2=classpath
javax.inject:javax.inject:1=classpath
-javax.xml.bind:jaxb-api:2.3.1=classpath
+net.java.dev.jna:jna-platform:5.6.0=classpath
+net.java.dev.jna:jna:5.6.0=classpath
net.sf.jopt-simple:jopt-simple:4.9=classpath
net.sf.kxml:kxml2:2.3.0=classpath
-net.sf.proguard:proguard-base:6.0.3=classpath
-net.sf.proguard:proguard-gradle:6.0.3=classpath
-org.antlr:antlr4:4.5.3=classpath
-org.apache.commons:commons-compress:1.12=classpath
-org.apache.httpcomponents:httpclient:4.5.6=classpath
-org.apache.httpcomponents:httpcore:4.4.10=classpath
+org.apache.commons:commons-compress:1.20=classpath
+org.apache.httpcomponents:httpclient:4.5.13=classpath
+org.apache.httpcomponents:httpcore:4.4.13=classpath
org.apache.httpcomponents:httpmime:4.5.6=classpath
-org.bouncycastle:bcpkix-jdk15on:1.56=classpath
-org.bouncycastle:bcprov-jdk15on:1.56=classpath
-org.checkerframework:checker-qual:2.11.1=classpath
-org.glassfish.jaxb:jaxb-runtime:2.3.1=classpath
-org.glassfish.jaxb:txw2:2.3.1=classpath
+org.bitbucket.b_c:jose4j:0.7.0=classpath
+org.bouncycastle:bcpkix-jdk15on:1.67=classpath
+org.bouncycastle:bcprov-jdk15on:1.67=classpath
+org.checkerframework:checker-qual:3.5.0=classpath
+org.codehaus.mojo:animal-sniffer-annotations:1.19=classpath
+org.glassfish.jaxb:jaxb-runtime:2.3.2=classpath
+org.glassfish.jaxb:txw2:2.3.2=classpath
org.jdom:jdom2:2.0.6=classpath
-org.jetbrains.intellij.deps:trove4j:1.0.20181211=classpath
-org.jetbrains.kotlin:kotlin-android-extensions:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-annotation-processing-gradle:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-build-common:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-compiler-embeddable:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-compiler-runner:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-daemon-client:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-daemon-embeddable:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-native-utils:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-project-model:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-reflect:1.3.72=classpath
-org.jetbrains.kotlin:kotlin-scripting-common:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-scripting-jvm:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-stdlib-common:1.3.72=classpath
-org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.72=classpath
-org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.72=classpath
-org.jetbrains.kotlin:kotlin-stdlib:1.3.72=classpath
-org.jetbrains.kotlin:kotlin-tooling-metadata:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-util-io:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-util-klib:1.5.31=classpath
+org.jetbrains.intellij.deps:trove4j:1.0.20200330=classpath
+org.jetbrains.kotlin:kotlin-android-extensions:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-annotation-processing-gradle:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-build-common:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-compiler-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-compiler-runner:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-daemon-client:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-daemon-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin-idea:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-native-utils:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-project-model:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-reflect:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-scripting-common:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-scripting-jvm:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-stdlib-common:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-stdlib:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-tooling-core:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-tooling-metadata:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-util-io:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-util-klib:1.7.10=classpath
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.0=classpath
-org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0=classpath
-org.jetbrains.trove4j:trove4j:20160824=classpath
org.jetbrains:annotations:13.0=classpath
org.json:json:20180813=classpath
-org.jvnet.staxex:stax-ex:1.8=classpath
-org.ow2.asm:asm-analysis:7.0=classpath
-org.ow2.asm:asm-commons:7.0=classpath
-org.ow2.asm:asm-tree:7.0=classpath
-org.ow2.asm:asm-util:7.0=classpath
-org.ow2.asm:asm:7.0=classpath
-org.tensorflow:tensorflow-lite-metadata:0.1.0-rc1=classpath
+org.jvnet.staxex:stax-ex:1.8.1=classpath
+org.ow2.asm:asm-analysis:9.1=classpath
+org.ow2.asm:asm-commons:9.1=classpath
+org.ow2.asm:asm-tree:9.1=classpath
+org.ow2.asm:asm-util:9.1=classpath
+org.ow2.asm:asm:9.1=classpath
+org.slf4j:slf4j-api:1.7.30=classpath
+org.tensorflow:tensorflow-lite-metadata:0.1.0-rc2=classpath
+xerces:xercesImpl:2.12.0=classpath
+xml-apis:xml-apis:1.4.01=classpath
empty=
diff --git a/dev/integration_tests/android_embedding_v2_smoke_test/android/project-app.lockfile b/dev/integration_tests/android_embedding_v2_smoke_test/android/project-app.lockfile
index 178876e..e0e5b2b 100644
--- a/dev/integration_tests/android_embedding_v2_smoke_test/android/project-app.lockfile
+++ b/dev/integration_tests/android_embedding_v2_smoke_test/android/project-app.lockfile
@@ -21,8 +21,8 @@
androidx.tracing:tracing:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
androidx.versionedparcelable:versionedparcelable:1.1.1=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
androidx.viewpager:viewpager:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
-androidx.window:window-java:1.0.0-beta03=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
-androidx.window:window:1.0.0-beta03=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.window:window-java:1.0.0-beta04=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.window:window:1.0.0-beta04=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
com.android.tools.analytics-library:protos:27.1.3=lintClassPath
com.android.tools.analytics-library:shared:27.1.3=lintClassPath
com.android.tools.analytics-library:tracker:27.1.3=lintClassPath
@@ -74,6 +74,7 @@
javax.activation:javax.activation-api:1.2.0=lintClassPath
javax.inject:javax.inject:1=lintClassPath
javax.xml.bind:jaxb-api:2.3.1=lintClassPath
+net.java.dev.jna:jna:5.6.0=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
net.sf.jopt-simple:jopt-simple:4.9=lintClassPath
net.sf.kxml:kxml2:2.3.0=lintClassPath
org.apache.commons:commons-compress:1.12=lintClassPath
@@ -87,21 +88,25 @@
org.codehaus.mojo:animal-sniffer-annotations:1.18=lintClassPath
org.glassfish.jaxb:jaxb-runtime:2.3.1=lintClassPath
org.glassfish.jaxb:txw2:2.3.1=lintClassPath
-org.jetbrains.intellij.deps:trove4j:1.0.20181211=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
-org.jetbrains.kotlin:kotlin-compiler-embeddable:1.5.31=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
-org.jetbrains.kotlin:kotlin-daemon-embeddable:1.5.31=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
-org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:1.5.31=kotlinKlibCommonizerClasspath
+org.jacoco:org.jacoco.agent:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.ant:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.core:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.report:0.8.7=androidJacocoAnt
+org.jetbrains.intellij.deps:trove4j:1.0.20200330=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
+org.jetbrains.kotlin:kotlin-compiler-embeddable:1.7.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
+org.jetbrains.kotlin:kotlin-daemon-embeddable:1.7.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
+org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:1.7.10=kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-reflect:1.3.72=lintClassPath
-org.jetbrains.kotlin:kotlin-reflect:1.5.31=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
-org.jetbrains.kotlin:kotlin-script-runtime:1.5.31=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
+org.jetbrains.kotlin:kotlin-reflect:1.7.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
+org.jetbrains.kotlin:kotlin-script-runtime:1.7.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-stdlib-common:1.3.72=lintClassPath
-org.jetbrains.kotlin:kotlin-stdlib-common:1.5.31=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlin:kotlin-stdlib-common:1.7.10=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.72=lintClassPath
-org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.5.31=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.10=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.72=lintClassPath
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.30=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.jetbrains.kotlin:kotlin-stdlib:1.3.72=lintClassPath
-org.jetbrains.kotlin:kotlin-stdlib:1.5.31=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlin:kotlin-stdlib:1.7.10=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.2=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
@@ -109,8 +114,12 @@
org.jetbrains:annotations:13.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,lintClassPath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.jvnet.staxex:stax-ex:1.8=lintClassPath
org.ow2.asm:asm-analysis:7.0=lintClassPath
+org.ow2.asm:asm-analysis:9.1=androidJacocoAnt
org.ow2.asm:asm-commons:7.0=lintClassPath
+org.ow2.asm:asm-commons:9.1=androidJacocoAnt
org.ow2.asm:asm-tree:7.0=lintClassPath
+org.ow2.asm:asm-tree:9.1=androidJacocoAnt
org.ow2.asm:asm-util:7.0=lintClassPath
org.ow2.asm:asm:7.0=lintClassPath
-empty=androidApis,androidTestApiDependenciesMetadata,androidTestCompileOnlyDependenciesMetadata,androidTestDebugApiDependenciesMetadata,androidTestDebugCompileOnlyDependenciesMetadata,androidTestDebugImplementationDependenciesMetadata,androidTestDebugIntransitiveDependenciesMetadata,androidTestDebugRuntimeOnlyDependenciesMetadata,androidTestImplementationDependenciesMetadata,androidTestIntransitiveDependenciesMetadata,androidTestProfileApiDependenciesMetadata,androidTestProfileCompileOnlyDependenciesMetadata,androidTestProfileImplementationDependenciesMetadata,androidTestProfileIntransitiveDependenciesMetadata,androidTestProfileRuntimeOnlyDependenciesMetadata,androidTestReleaseApiDependenciesMetadata,androidTestReleaseCompileOnlyDependenciesMetadata,androidTestReleaseImplementationDependenciesMetadata,androidTestReleaseIntransitiveDependenciesMetadata,androidTestReleaseRuntimeOnlyDependenciesMetadata,androidTestRuntimeOnlyDependenciesMetadata,androidTestUtil,compile,compileOnlyDependenciesMetadata,coreLibraryDesugaring,debugAndroidTestAnnotationProcessorClasspath,debugAndroidTestApiDependenciesMetadata,debugAndroidTestCompileOnlyDependenciesMetadata,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestIntransitiveDependenciesMetadata,debugAndroidTestRuntimeClasspath,debugAndroidTestRuntimeOnlyDependenciesMetadata,debugAnnotationProcessorClasspath,debugCompile,debugCompileOnly,debugCompileOnlyDependenciesMetadata,debugIntransitiveDependenciesMetadata,debugReverseMetadataValues,debugRuntimeOnlyDependenciesMetadata,debugUnitTestAnnotationProcessorClasspath,debugUnitTestApiDependenciesMetadata,debugUnitTestCompileOnlyDependenciesMetadata,debugUnitTestImplementationDependenciesMetadata,debugUnitTestIntransitiveDependenciesMetadata,debugUnitTestRuntimeOnlyDependenciesMetadata,debugWearBundling,intransitiveDependenciesMetadata,kotlinCompilerPluginClasspath,kotlinCompilerPluginClasspathDebug,kotlinCompilerPluginClasspathDebugAndroidTest,kotlinCompilerPluginClasspathDebugUnitTest,kotlinCompilerPluginClasspathProfile,kotlinCompilerPluginClasspathProfileUnitTest,kotlinCompilerPluginClasspathRelease,kotlinCompilerPluginClasspathReleaseUnitTest,kotlinNativeCompilerPluginClasspath,lintChecks,lintPublish,profileAnnotationProcessorClasspath,profileCompile,profileCompileOnly,profileCompileOnlyDependenciesMetadata,profileIntransitiveDependenciesMetadata,profileReverseMetadataValues,profileRuntimeOnlyDependenciesMetadata,profileUnitTestAnnotationProcessorClasspath,profileUnitTestApiDependenciesMetadata,profileUnitTestCompileOnlyDependenciesMetadata,profileUnitTestImplementationDependenciesMetadata,profileUnitTestIntransitiveDependenciesMetadata,profileUnitTestRuntimeOnlyDependenciesMetadata,profileWearBundling,releaseAnnotationProcessorClasspath,releaseCompile,releaseCompileOnly,releaseCompileOnlyDependenciesMetadata,releaseIntransitiveDependenciesMetadata,releaseReverseMetadataValues,releaseRuntimeOnlyDependenciesMetadata,releaseUnitTestAnnotationProcessorClasspath,releaseUnitTestApiDependenciesMetadata,releaseUnitTestCompileOnlyDependenciesMetadata,releaseUnitTestImplementationDependenciesMetadata,releaseUnitTestIntransitiveDependenciesMetadata,releaseUnitTestRuntimeOnlyDependenciesMetadata,releaseWearBundling,runtimeOnlyDependenciesMetadata,testApiDependenciesMetadata,testCompile,testCompileOnlyDependenciesMetadata,testDebugApiDependenciesMetadata,testDebugCompileOnlyDependenciesMetadata,testDebugImplementationDependenciesMetadata,testDebugIntransitiveDependenciesMetadata,testDebugRuntimeOnlyDependenciesMetadata,testImplementationDependenciesMetadata,testIntransitiveDependenciesMetadata,testProfileApiDependenciesMetadata,testProfileCompileOnlyDependenciesMetadata,testProfileImplementationDependenciesMetadata,testProfileIntransitiveDependenciesMetadata,testProfileRuntimeOnlyDependenciesMetadata,testReleaseApiDependenciesMetadata,testReleaseCompileOnlyDependenciesMetadata,testReleaseImplementationDependenciesMetadata,testReleaseIntransitiveDependenciesMetadata,testReleaseRuntimeOnlyDependenciesMetadata,testRuntimeOnlyDependenciesMetadata
+org.ow2.asm:asm:9.1=androidJacocoAnt
+empty=androidApis,androidJdkImage,androidTestApiDependenciesMetadata,androidTestCompileOnlyDependenciesMetadata,androidTestDebugApiDependenciesMetadata,androidTestDebugCompileOnlyDependenciesMetadata,androidTestDebugImplementationDependenciesMetadata,androidTestDebugIntransitiveDependenciesMetadata,androidTestDebugRuntimeOnlyDependenciesMetadata,androidTestImplementationDependenciesMetadata,androidTestIntransitiveDependenciesMetadata,androidTestProfileApiDependenciesMetadata,androidTestProfileCompileOnlyDependenciesMetadata,androidTestProfileImplementationDependenciesMetadata,androidTestProfileIntransitiveDependenciesMetadata,androidTestProfileRuntimeOnlyDependenciesMetadata,androidTestReleaseApiDependenciesMetadata,androidTestReleaseCompileOnlyDependenciesMetadata,androidTestReleaseImplementationDependenciesMetadata,androidTestReleaseIntransitiveDependenciesMetadata,androidTestReleaseRuntimeOnlyDependenciesMetadata,androidTestRuntimeOnlyDependenciesMetadata,androidTestUtil,compile,compileOnlyDependenciesMetadata,coreLibraryDesugaring,debugAndroidTestAnnotationProcessorClasspath,debugAndroidTestApiDependenciesMetadata,debugAndroidTestCompileOnlyDependenciesMetadata,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestIntransitiveDependenciesMetadata,debugAndroidTestRuntimeClasspath,debugAndroidTestRuntimeOnlyDependenciesMetadata,debugAnnotationProcessorClasspath,debugCompile,debugCompileOnly,debugCompileOnlyDependenciesMetadata,debugIntransitiveDependenciesMetadata,debugReverseMetadataValues,debugRuntimeOnlyDependenciesMetadata,debugUnitTestAnnotationProcessorClasspath,debugUnitTestApiDependenciesMetadata,debugUnitTestCompileOnlyDependenciesMetadata,debugUnitTestImplementationDependenciesMetadata,debugUnitTestIntransitiveDependenciesMetadata,debugUnitTestRuntimeOnlyDependenciesMetadata,debugWearBundling,intransitiveDependenciesMetadata,kotlinCompilerPluginClasspath,kotlinCompilerPluginClasspathDebug,kotlinCompilerPluginClasspathDebugAndroidTest,kotlinCompilerPluginClasspathDebugUnitTest,kotlinCompilerPluginClasspathProfile,kotlinCompilerPluginClasspathProfileUnitTest,kotlinCompilerPluginClasspathRelease,kotlinCompilerPluginClasspathReleaseUnitTest,kotlinNativeCompilerPluginClasspath,lintChecks,lintPublish,profileAnnotationProcessorClasspath,profileCompile,profileCompileOnly,profileCompileOnlyDependenciesMetadata,profileIntransitiveDependenciesMetadata,profileReverseMetadataValues,profileRuntimeOnlyDependenciesMetadata,profileUnitTestAnnotationProcessorClasspath,profileUnitTestApiDependenciesMetadata,profileUnitTestCompileOnlyDependenciesMetadata,profileUnitTestImplementationDependenciesMetadata,profileUnitTestIntransitiveDependenciesMetadata,profileUnitTestRuntimeOnlyDependenciesMetadata,profileWearBundling,releaseAnnotationProcessorClasspath,releaseCompile,releaseCompileOnly,releaseCompileOnlyDependenciesMetadata,releaseIntransitiveDependenciesMetadata,releaseReverseMetadataValues,releaseRuntimeOnlyDependenciesMetadata,releaseUnitTestAnnotationProcessorClasspath,releaseUnitTestApiDependenciesMetadata,releaseUnitTestCompileOnlyDependenciesMetadata,releaseUnitTestImplementationDependenciesMetadata,releaseUnitTestIntransitiveDependenciesMetadata,releaseUnitTestRuntimeOnlyDependenciesMetadata,releaseWearBundling,runtimeOnlyDependenciesMetadata,testApiDependenciesMetadata,testCompile,testCompileOnlyDependenciesMetadata,testDebugApiDependenciesMetadata,testDebugCompileOnlyDependenciesMetadata,testDebugImplementationDependenciesMetadata,testDebugIntransitiveDependenciesMetadata,testDebugRuntimeOnlyDependenciesMetadata,testFixturesApiDependenciesMetadata,testFixturesCompileOnlyDependenciesMetadata,testFixturesDebugApiDependenciesMetadata,testFixturesDebugCompileOnlyDependenciesMetadata,testFixturesDebugImplementationDependenciesMetadata,testFixturesDebugIntransitiveDependenciesMetadata,testFixturesDebugRuntimeOnlyDependenciesMetadata,testFixturesImplementationDependenciesMetadata,testFixturesIntransitiveDependenciesMetadata,testFixturesProfileApiDependenciesMetadata,testFixturesProfileCompileOnlyDependenciesMetadata,testFixturesProfileImplementationDependenciesMetadata,testFixturesProfileIntransitiveDependenciesMetadata,testFixturesProfileRuntimeOnlyDependenciesMetadata,testFixturesReleaseApiDependenciesMetadata,testFixturesReleaseCompileOnlyDependenciesMetadata,testFixturesReleaseImplementationDependenciesMetadata,testFixturesReleaseIntransitiveDependenciesMetadata,testFixturesReleaseRuntimeOnlyDependenciesMetadata,testFixturesRuntimeOnlyDependenciesMetadata,testImplementationDependenciesMetadata,testIntransitiveDependenciesMetadata,testProfileApiDependenciesMetadata,testProfileCompileOnlyDependenciesMetadata,testProfileImplementationDependenciesMetadata,testProfileIntransitiveDependenciesMetadata,testProfileRuntimeOnlyDependenciesMetadata,testReleaseApiDependenciesMetadata,testReleaseCompileOnlyDependenciesMetadata,testReleaseImplementationDependenciesMetadata,testReleaseIntransitiveDependenciesMetadata,testReleaseRuntimeOnlyDependenciesMetadata,testRuntimeOnlyDependenciesMetadata
diff --git a/dev/integration_tests/android_embedding_v2_smoke_test/android/project-battery.lockfile b/dev/integration_tests/android_embedding_v2_smoke_test/android/project-battery.lockfile
index 813cc34..973309f 100644
--- a/dev/integration_tests/android_embedding_v2_smoke_test/android/project-battery.lockfile
+++ b/dev/integration_tests/android_embedding_v2_smoke_test/android/project-battery.lockfile
@@ -21,8 +21,8 @@
androidx.tracing:tracing:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
androidx.versionedparcelable:versionedparcelable:1.1.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
androidx.viewpager:viewpager:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
-androidx.window:window-java:1.0.0-beta03=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
-androidx.window:window:1.0.0-beta03=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.window:window-java:1.0.0-beta04=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.window:window:1.0.0-beta04=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
com.android.tools.analytics-library:protos:27.1.3=lintClassPath
com.android.tools.analytics-library:shared:27.1.3=lintClassPath
com.android.tools.analytics-library:tracker:27.1.3=lintClassPath
@@ -87,6 +87,10 @@
org.codehaus.mojo:animal-sniffer-annotations:1.18=lintClassPath
org.glassfish.jaxb:jaxb-runtime:2.3.1=lintClassPath
org.glassfish.jaxb:txw2:2.3.1=lintClassPath
+org.jacoco:org.jacoco.agent:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.ant:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.core:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.report:0.8.7=androidJacocoAnt
org.jetbrains.kotlin:kotlin-reflect:1.3.72=lintClassPath
org.jetbrains.kotlin:kotlin-stdlib-common:1.3.72=lintClassPath
org.jetbrains.kotlin:kotlin-stdlib-common:1.5.31=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
@@ -103,8 +107,12 @@
org.jetbrains:annotations:13.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,lintClassPath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.jvnet.staxex:stax-ex:1.8=lintClassPath
org.ow2.asm:asm-analysis:7.0=lintClassPath
+org.ow2.asm:asm-analysis:9.1=androidJacocoAnt
org.ow2.asm:asm-commons:7.0=lintClassPath
+org.ow2.asm:asm-commons:9.1=androidJacocoAnt
org.ow2.asm:asm-tree:7.0=lintClassPath
+org.ow2.asm:asm-tree:9.1=androidJacocoAnt
org.ow2.asm:asm-util:7.0=lintClassPath
org.ow2.asm:asm:7.0=lintClassPath
-empty=androidApis,androidTestUtil,compile,coreLibraryDesugaring,debugAndroidTestAnnotationProcessorClasspath,debugAnnotationProcessorClasspath,debugUnitTestAnnotationProcessorClasspath,lintChecks,lintPublish,profileAnnotationProcessorClasspath,profileUnitTestAnnotationProcessorClasspath,releaseAnnotationProcessorClasspath,releaseUnitTestAnnotationProcessorClasspath,testCompile
+org.ow2.asm:asm:9.1=androidJacocoAnt
+empty=androidApis,androidJdkImage,androidTestUtil,compile,coreLibraryDesugaring,debugAndroidTestAnnotationProcessorClasspath,debugAnnotationProcessorClasspath,debugUnitTestAnnotationProcessorClasspath,lintChecks,lintPublish,profileAnnotationProcessorClasspath,profileUnitTestAnnotationProcessorClasspath,releaseAnnotationProcessorClasspath,releaseUnitTestAnnotationProcessorClasspath,testCompile
diff --git a/dev/integration_tests/android_embedding_v2_smoke_test/android/settings.gradle b/dev/integration_tests/android_embedding_v2_smoke_test/android/settings.gradle
index 03ae72d..a020595 100644
--- a/dev/integration_tests/android_embedding_v2_smoke_test/android/settings.gradle
+++ b/dev/integration_tests/android_embedding_v2_smoke_test/android/settings.gradle
@@ -8,8 +8,6 @@
include ':app'
-enableFeaturePreview('ONE_LOCKFILE_PER_PROJECT')
-
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()
diff --git a/dev/integration_tests/android_embedding_v2_smoke_test/pubspec.yaml b/dev/integration_tests/android_embedding_v2_smoke_test/pubspec.yaml
index f961654..01c6025 100644
--- a/dev/integration_tests/android_embedding_v2_smoke_test/pubspec.yaml
+++ b/dev/integration_tests/android_embedding_v2_smoke_test/pubspec.yaml
@@ -30,11 +30,11 @@
battery_platform_interface: 2.0.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
collection: 1.17.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.9.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
plugin_platform_interface: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
flutter_test:
@@ -52,11 +52,11 @@
matcher: 0.12.16 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path: 1.8.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
flutter:
@@ -96,4 +96,4 @@
# For details regarding fonts from package dependencies,
# see https://flutter.dev/custom-fonts/#from-packages
-# PUBSPEC CHECKSUM: 7cef
+# PUBSPEC CHECKSUM: 9e17
diff --git a/dev/integration_tests/android_semantics_testing/android/build.gradle b/dev/integration_tests/android_semantics_testing/android/build.gradle
index 57ace36..a2a8866 100644
--- a/dev/integration_tests/android_semantics_testing/android/build.gradle
+++ b/dev/integration_tests/android_semantics_testing/android/build.gradle
@@ -7,14 +7,14 @@
// See dev/tools/bin/generate_gradle_lockfiles.dart.
buildscript {
- ext.kotlin_version = '1.5.31'
+ ext.kotlin_version = '1.7.10'
repositories {
google()
mavenCentral()
}
dependencies {
- classpath 'com.android.tools.build:gradle:4.1.3'
+ classpath 'com.android.tools.build:gradle:7.3.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
diff --git a/dev/integration_tests/android_semantics_testing/android/buildscript-gradle.lockfile b/dev/integration_tests/android_semantics_testing/android/buildscript-gradle.lockfile
index 2577f0a..eb60580 100644
--- a/dev/integration_tests/android_semantics_testing/android/buildscript-gradle.lockfile
+++ b/dev/integration_tests/android_semantics_testing/android/buildscript-gradle.lockfile
@@ -1,120 +1,152 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
-androidx.databinding:databinding-common:4.1.3=classpath
-androidx.databinding:databinding-compiler-common:4.1.3=classpath
-com.android.databinding:baseLibrary:4.1.3=classpath
-com.android.tools.analytics-library:crash:27.1.3=classpath
-com.android.tools.analytics-library:protos:27.1.3=classpath
-com.android.tools.analytics-library:shared:27.1.3=classpath
-com.android.tools.analytics-library:tracker:27.1.3=classpath
-com.android.tools.build.jetifier:jetifier-core:1.0.0-beta09=classpath
-com.android.tools.build.jetifier:jetifier-processor:1.0.0-beta09=classpath
-com.android.tools.build:aapt2-proto:4.1.3-6503028=classpath
-com.android.tools.build:aaptcompiler:4.1.3=classpath
-com.android.tools.build:apksig:4.1.3=classpath
-com.android.tools.build:apkzlib:4.1.3=classpath
-com.android.tools.build:builder-model:4.1.3=classpath
-com.android.tools.build:builder-test-api:4.1.3=classpath
-com.android.tools.build:builder:4.1.3=classpath
-com.android.tools.build:bundletool:0.14.0=classpath
-com.android.tools.build:gradle-api:4.1.3=classpath
-com.android.tools.build:gradle:4.1.3=classpath
-com.android.tools.build:manifest-merger:27.1.3=classpath
+androidx.databinding:databinding-common:7.3.0=classpath
+androidx.databinding:databinding-compiler-common:7.3.0=classpath
+com.android.databinding:baseLibrary:7.3.0=classpath
+com.android.tools.analytics-library:crash:30.3.0=classpath
+com.android.tools.analytics-library:protos:30.3.0=classpath
+com.android.tools.analytics-library:shared:30.3.0=classpath
+com.android.tools.analytics-library:tracker:30.3.0=classpath
+com.android.tools.build.jetifier:jetifier-core:1.0.0-beta10=classpath
+com.android.tools.build.jetifier:jetifier-processor:1.0.0-beta10=classpath
+com.android.tools.build:aapt2-proto:7.3.0-8691043=classpath
+com.android.tools.build:aaptcompiler:7.3.0=classpath
+com.android.tools.build:apksig:7.3.0=classpath
+com.android.tools.build:apkzlib:7.3.0=classpath
+com.android.tools.build:builder-model:7.3.0=classpath
+com.android.tools.build:builder-test-api:7.3.0=classpath
+com.android.tools.build:builder:7.3.0=classpath
+com.android.tools.build:bundletool:1.9.0=classpath
+com.android.tools.build:gradle-api:7.3.0=classpath
+com.android.tools.build:gradle:7.3.0=classpath
+com.android.tools.build:manifest-merger:30.3.0=classpath
com.android.tools.build:transform-api:2.0.0-deprecated-use-gradle-api=classpath
-com.android.tools.ddms:ddmlib:27.1.3=classpath
-com.android.tools.layoutlib:layoutlib-api:27.1.3=classpath
-com.android.tools.lint:lint-gradle-api:27.1.3=classpath
-com.android.tools.lint:lint-model:27.1.3=classpath
-com.android.tools:annotations:27.1.3=classpath
-com.android.tools:common:27.1.3=classpath
-com.android.tools:dvlib:27.1.3=classpath
-com.android.tools:repository:27.1.3=classpath
-com.android.tools:sdk-common:27.1.3=classpath
-com.android.tools:sdklib:27.1.3=classpath
-com.android:signflinger:4.1.3=classpath
-com.android:zipflinger:4.1.3=classpath
+com.android.tools.ddms:ddmlib:30.3.0=classpath
+com.android.tools.layoutlib:layoutlib-api:30.3.0=classpath
+com.android.tools.lint:lint-model:30.3.0=classpath
+com.android.tools.lint:lint-typedef-remover:30.3.0=classpath
+com.android.tools.utp:android-device-provider-ddmlib-proto:30.3.0=classpath
+com.android.tools.utp:android-device-provider-gradle-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-host-additional-test-output-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-host-coverage-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-host-retention-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-result-listener-gradle-proto:30.3.0=classpath
+com.android.tools:annotations:30.3.0=classpath
+com.android.tools:common:30.3.0=classpath
+com.android.tools:dvlib:30.3.0=classpath
+com.android.tools:repository:30.3.0=classpath
+com.android.tools:sdk-common:30.3.0=classpath
+com.android.tools:sdklib:30.3.0=classpath
+com.android:signflinger:7.3.0=classpath
+com.android:zipflinger:7.3.0=classpath
com.github.gundy:semver4j:0.16.4=classpath
+com.google.android:annotations:4.1.1.4=classpath
+com.google.api.grpc:proto-google-common-protos:2.0.1=classpath
com.google.auto.value:auto-value-annotations:1.6.2=classpath
com.google.code.findbugs:jsr305:3.0.2=classpath
-com.google.code.gson:gson:2.8.6=classpath
+com.google.code.gson:gson:2.8.9=classpath
com.google.crypto.tink:tink:1.3.0-rc2=classpath
-com.google.errorprone:error_prone_annotations:2.3.4=classpath
+com.google.dagger:dagger:2.28.3=classpath
+com.google.errorprone:error_prone_annotations:2.4.0=classpath
com.google.flatbuffers:flatbuffers-java:1.12.0=classpath
com.google.guava:failureaccess:1.0.1=classpath
-com.google.guava:guava:29.0-jre=classpath
+com.google.guava:guava:30.1-jre=classpath
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=classpath
com.google.j2objc:j2objc-annotations:1.3=classpath
com.google.jimfs:jimfs:1.1=classpath
-com.google.protobuf:protobuf-java-util:3.10.0=classpath
-com.google.protobuf:protobuf-java:3.10.0=classpath
-com.google.test.platform:core-proto:0.0.2-dev=classpath
+com.google.protobuf:protobuf-java-util:3.17.2=classpath
+com.google.protobuf:protobuf-java:3.17.2=classpath
+com.google.testing.platform:core-proto:0.0.8-alpha07=classpath
com.googlecode.json-simple:json-simple:1.1=classpath
com.googlecode.juniversalchardet:juniversalchardet:1.0.3=classpath
com.squareup:javapoet:1.10.0=classpath
com.squareup:javawriter:2.5.0=classpath
com.sun.activation:javax.activation:1.2.0=classpath
-com.sun.istack:istack-commons-runtime:3.0.7=classpath
-com.sun.xml.fastinfoset:FastInfoset:1.2.15=classpath
-commons-codec:commons-codec:1.10=classpath
+com.sun.istack:istack-commons-runtime:3.0.8=classpath
+com.sun.xml.fastinfoset:FastInfoset:1.2.16=classpath
+commons-codec:commons-codec:1.11=classpath
commons-io:commons-io:2.4=classpath
commons-logging:commons-logging:1.2=classpath
de.undercouch:gradle-download-task:4.1.1=classpath
-it.unimi.dsi:fastutil:7.2.0=classpath
-javax.activation:javax.activation-api:1.2.0=classpath
+io.grpc:grpc-api:1.39.0=classpath
+io.grpc:grpc-context:1.39.0=classpath
+io.grpc:grpc-core:1.39.0=classpath
+io.grpc:grpc-netty:1.39.0=classpath
+io.grpc:grpc-protobuf-lite:1.39.0=classpath
+io.grpc:grpc-protobuf:1.39.0=classpath
+io.grpc:grpc-stub:1.39.0=classpath
+io.netty:netty-buffer:4.1.52.Final=classpath
+io.netty:netty-codec-http2:4.1.52.Final=classpath
+io.netty:netty-codec-http:4.1.52.Final=classpath
+io.netty:netty-codec-socks:4.1.52.Final=classpath
+io.netty:netty-codec:4.1.52.Final=classpath
+io.netty:netty-common:4.1.52.Final=classpath
+io.netty:netty-handler-proxy:4.1.52.Final=classpath
+io.netty:netty-handler:4.1.52.Final=classpath
+io.netty:netty-resolver:4.1.52.Final=classpath
+io.netty:netty-transport:4.1.52.Final=classpath
+io.perfmark:perfmark-api:0.23.0=classpath
+it.unimi.dsi:fastutil:8.4.0=classpath
+jakarta.activation:jakarta.activation-api:1.2.1=classpath
+jakarta.xml.bind:jakarta.xml.bind-api:2.3.2=classpath
+javax.annotation:javax.annotation-api:1.3.2=classpath
javax.inject:javax.inject:1=classpath
-javax.xml.bind:jaxb-api:2.3.1=classpath
+net.java.dev.jna:jna-platform:5.6.0=classpath
+net.java.dev.jna:jna:5.6.0=classpath
net.sf.jopt-simple:jopt-simple:4.9=classpath
net.sf.kxml:kxml2:2.3.0=classpath
-net.sf.proguard:proguard-base:6.0.3=classpath
-net.sf.proguard:proguard-gradle:6.0.3=classpath
-org.antlr:antlr4:4.5.3=classpath
-org.apache.commons:commons-compress:1.12=classpath
-org.apache.httpcomponents:httpclient:4.5.6=classpath
-org.apache.httpcomponents:httpcore:4.4.10=classpath
+org.apache.commons:commons-compress:1.20=classpath
+org.apache.httpcomponents:httpclient:4.5.13=classpath
+org.apache.httpcomponents:httpcore:4.4.13=classpath
org.apache.httpcomponents:httpmime:4.5.6=classpath
-org.bouncycastle:bcpkix-jdk15on:1.56=classpath
-org.bouncycastle:bcprov-jdk15on:1.56=classpath
-org.checkerframework:checker-qual:2.11.1=classpath
-org.glassfish.jaxb:jaxb-runtime:2.3.1=classpath
-org.glassfish.jaxb:txw2:2.3.1=classpath
+org.bitbucket.b_c:jose4j:0.7.0=classpath
+org.bouncycastle:bcpkix-jdk15on:1.67=classpath
+org.bouncycastle:bcprov-jdk15on:1.67=classpath
+org.checkerframework:checker-qual:3.5.0=classpath
+org.codehaus.mojo:animal-sniffer-annotations:1.19=classpath
+org.glassfish.jaxb:jaxb-runtime:2.3.2=classpath
+org.glassfish.jaxb:txw2:2.3.2=classpath
org.jdom:jdom2:2.0.6=classpath
-org.jetbrains.intellij.deps:trove4j:1.0.20181211=classpath
-org.jetbrains.kotlin:kotlin-android-extensions:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-annotation-processing-gradle:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-build-common:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-compiler-embeddable:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-compiler-runner:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-daemon-client:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-daemon-embeddable:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-native-utils:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-project-model:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-reflect:1.3.72=classpath
-org.jetbrains.kotlin:kotlin-scripting-common:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-scripting-jvm:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-stdlib-common:1.3.72=classpath
-org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.72=classpath
-org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.72=classpath
-org.jetbrains.kotlin:kotlin-stdlib:1.3.72=classpath
-org.jetbrains.kotlin:kotlin-tooling-metadata:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-util-io:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-util-klib:1.5.31=classpath
+org.jetbrains.intellij.deps:trove4j:1.0.20200330=classpath
+org.jetbrains.kotlin:kotlin-android-extensions:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-annotation-processing-gradle:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-build-common:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-compiler-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-compiler-runner:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-daemon-client:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-daemon-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin-idea:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-native-utils:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-project-model:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-reflect:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-scripting-common:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-scripting-jvm:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-stdlib-common:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-stdlib:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-tooling-core:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-tooling-metadata:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-util-io:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-util-klib:1.7.10=classpath
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.0=classpath
-org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0=classpath
-org.jetbrains.trove4j:trove4j:20160824=classpath
org.jetbrains:annotations:13.0=classpath
org.json:json:20180813=classpath
-org.jvnet.staxex:stax-ex:1.8=classpath
-org.ow2.asm:asm-analysis:7.0=classpath
-org.ow2.asm:asm-commons:7.0=classpath
-org.ow2.asm:asm-tree:7.0=classpath
-org.ow2.asm:asm-util:7.0=classpath
-org.ow2.asm:asm:7.0=classpath
-org.tensorflow:tensorflow-lite-metadata:0.1.0-rc1=classpath
+org.jvnet.staxex:stax-ex:1.8.1=classpath
+org.ow2.asm:asm-analysis:9.1=classpath
+org.ow2.asm:asm-commons:9.1=classpath
+org.ow2.asm:asm-tree:9.1=classpath
+org.ow2.asm:asm-util:9.1=classpath
+org.ow2.asm:asm:9.1=classpath
+org.slf4j:slf4j-api:1.7.30=classpath
+org.tensorflow:tensorflow-lite-metadata:0.1.0-rc2=classpath
+xerces:xercesImpl:2.12.0=classpath
+xml-apis:xml-apis:1.4.01=classpath
empty=
diff --git a/dev/integration_tests/android_semantics_testing/android/project-app.lockfile b/dev/integration_tests/android_semantics_testing/android/project-app.lockfile
index df07b3a..77a5232 100644
--- a/dev/integration_tests/android_semantics_testing/android/project-app.lockfile
+++ b/dev/integration_tests/android_semantics_testing/android/project-app.lockfile
@@ -100,6 +100,10 @@
org.hamcrest:hamcrest-core:1.3=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.hamcrest:hamcrest-integration:1.3=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.hamcrest:hamcrest-library:1.3=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jacoco:org.jacoco.agent:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.ant:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.core:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.report:0.8.7=androidJacocoAnt
org.jetbrains.kotlin:kotlin-reflect:1.3.72=lintClassPath
org.jetbrains.kotlin:kotlin-stdlib-common:1.3.72=lintClassPath
org.jetbrains.kotlin:kotlin-stdlib-common:1.5.31=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
@@ -116,8 +120,12 @@
org.jetbrains:annotations:13.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,lintClassPath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.jvnet.staxex:stax-ex:1.8=lintClassPath
org.ow2.asm:asm-analysis:7.0=lintClassPath
+org.ow2.asm:asm-analysis:9.1=androidJacocoAnt
org.ow2.asm:asm-commons:7.0=lintClassPath
+org.ow2.asm:asm-commons:9.1=androidJacocoAnt
org.ow2.asm:asm-tree:7.0=lintClassPath
+org.ow2.asm:asm-tree:9.1=androidJacocoAnt
org.ow2.asm:asm-util:7.0=lintClassPath
org.ow2.asm:asm:7.0=lintClassPath
-empty=androidApis,androidTestUtil,compile,coreLibraryDesugaring,debugAndroidTestAnnotationProcessorClasspath,debugAndroidTestRuntimeClasspath,debugAnnotationProcessorClasspath,debugReverseMetadataValues,debugUnitTestAnnotationProcessorClasspath,debugWearBundling,lintChecks,lintPublish,profileAnnotationProcessorClasspath,profileReverseMetadataValues,profileUnitTestAnnotationProcessorClasspath,profileWearBundling,releaseAnnotationProcessorClasspath,releaseReverseMetadataValues,releaseUnitTestAnnotationProcessorClasspath,releaseWearBundling,testCompile
+org.ow2.asm:asm:9.1=androidJacocoAnt
+empty=androidApis,androidJdkImage,androidTestUtil,compile,coreLibraryDesugaring,debugAndroidTestAnnotationProcessorClasspath,debugAndroidTestRuntimeClasspath,debugAnnotationProcessorClasspath,debugReverseMetadataValues,debugUnitTestAnnotationProcessorClasspath,debugWearBundling,lintChecks,lintPublish,profileAnnotationProcessorClasspath,profileReverseMetadataValues,profileUnitTestAnnotationProcessorClasspath,profileWearBundling,releaseAnnotationProcessorClasspath,releaseReverseMetadataValues,releaseUnitTestAnnotationProcessorClasspath,releaseWearBundling,testCompile
diff --git a/dev/integration_tests/android_semantics_testing/android/project-integration_test.lockfile b/dev/integration_tests/android_semantics_testing/android/project-integration_test.lockfile
index 9d48dc0..79f963c 100644
--- a/dev/integration_tests/android_semantics_testing/android/project-integration_test.lockfile
+++ b/dev/integration_tests/android_semantics_testing/android/project-integration_test.lockfile
@@ -99,6 +99,10 @@
org.hamcrest:hamcrest-core:1.3=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.hamcrest:hamcrest-integration:1.3=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.hamcrest:hamcrest-library:1.3=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jacoco:org.jacoco.agent:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.ant:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.core:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.report:0.8.7=androidJacocoAnt
org.jetbrains.kotlin:kotlin-reflect:1.3.72=lintClassPath
org.jetbrains.kotlin:kotlin-stdlib-common:1.3.72=lintClassPath
org.jetbrains.kotlin:kotlin-stdlib-common:1.5.31=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
@@ -115,8 +119,12 @@
org.jetbrains:annotations:13.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,lintClassPath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.jvnet.staxex:stax-ex:1.8=lintClassPath
org.ow2.asm:asm-analysis:7.0=lintClassPath
+org.ow2.asm:asm-analysis:9.1=androidJacocoAnt
org.ow2.asm:asm-commons:7.0=lintClassPath
+org.ow2.asm:asm-commons:9.1=androidJacocoAnt
org.ow2.asm:asm-tree:7.0=lintClassPath
+org.ow2.asm:asm-tree:9.1=androidJacocoAnt
org.ow2.asm:asm-util:7.0=lintClassPath
org.ow2.asm:asm:7.0=lintClassPath
-empty=androidApis,androidTestUtil,compile,coreLibraryDesugaring,debugAndroidTestAnnotationProcessorClasspath,debugAnnotationProcessorClasspath,debugUnitTestAnnotationProcessorClasspath,lintChecks,lintPublish,profileAnnotationProcessorClasspath,profileUnitTestAnnotationProcessorClasspath,releaseAnnotationProcessorClasspath,releaseUnitTestAnnotationProcessorClasspath,testCompile
+org.ow2.asm:asm:9.1=androidJacocoAnt
+empty=androidApis,androidJdkImage,androidTestUtil,compile,coreLibraryDesugaring,debugAndroidTestAnnotationProcessorClasspath,debugAnnotationProcessorClasspath,debugUnitTestAnnotationProcessorClasspath,lintChecks,lintPublish,profileAnnotationProcessorClasspath,profileUnitTestAnnotationProcessorClasspath,releaseAnnotationProcessorClasspath,releaseUnitTestAnnotationProcessorClasspath,testCompile
diff --git a/dev/integration_tests/android_semantics_testing/android/settings.gradle b/dev/integration_tests/android_semantics_testing/android/settings.gradle
index 03ae72d..a020595 100644
--- a/dev/integration_tests/android_semantics_testing/android/settings.gradle
+++ b/dev/integration_tests/android_semantics_testing/android/settings.gradle
@@ -8,8 +8,6 @@
include ':app'
-enableFeaturePreview('ONE_LOCKFILE_PER_PROJECT')
-
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()
diff --git a/dev/integration_tests/android_semantics_testing/pubspec.yaml b/dev/integration_tests/android_semantics_testing/pubspec.yaml
index 6c4b843..eb7899b 100644
--- a/dev/integration_tests/android_semantics_testing/pubspec.yaml
+++ b/dev/integration_tests/android_semantics_testing/pubspec.yaml
@@ -11,10 +11,10 @@
flutter_test:
sdk: flutter
pub_semver: 2.1.4
- test: 1.24.3
+ test: 1.24.4
- _fe_analyzer_shared: 61.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- analyzer: 5.13.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ _fe_analyzer_shared: 62.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ analyzer: 6.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
args: 2.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
async: 2.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -24,6 +24,7 @@
convert: 3.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
coverage: 1.6.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
crypto: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ dart_internal: 0.2.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
fake_async: 1.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
file: 6.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
frontend_server_client: 3.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -48,16 +49,17 @@
source_map_stack_trace: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_maps: 0.10.12 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_core: 0.5.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_core: 0.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- vm_service: 11.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ vm_service: 11.7.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -65,4 +67,4 @@
flutter:
uses-material-design: true
-# PUBSPEC CHECKSUM: 94f0
+# PUBSPEC CHECKSUM: 79da
diff --git a/dev/integration_tests/android_views/android/build.gradle b/dev/integration_tests/android_views/android/build.gradle
index 57ace36..a2a8866 100644
--- a/dev/integration_tests/android_views/android/build.gradle
+++ b/dev/integration_tests/android_views/android/build.gradle
@@ -7,14 +7,14 @@
// See dev/tools/bin/generate_gradle_lockfiles.dart.
buildscript {
- ext.kotlin_version = '1.5.31'
+ ext.kotlin_version = '1.7.10'
repositories {
google()
mavenCentral()
}
dependencies {
- classpath 'com.android.tools.build:gradle:4.1.3'
+ classpath 'com.android.tools.build:gradle:7.3.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
diff --git a/dev/integration_tests/android_views/android/buildscript-gradle.lockfile b/dev/integration_tests/android_views/android/buildscript-gradle.lockfile
index 2577f0a..eb60580 100644
--- a/dev/integration_tests/android_views/android/buildscript-gradle.lockfile
+++ b/dev/integration_tests/android_views/android/buildscript-gradle.lockfile
@@ -1,120 +1,152 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
-androidx.databinding:databinding-common:4.1.3=classpath
-androidx.databinding:databinding-compiler-common:4.1.3=classpath
-com.android.databinding:baseLibrary:4.1.3=classpath
-com.android.tools.analytics-library:crash:27.1.3=classpath
-com.android.tools.analytics-library:protos:27.1.3=classpath
-com.android.tools.analytics-library:shared:27.1.3=classpath
-com.android.tools.analytics-library:tracker:27.1.3=classpath
-com.android.tools.build.jetifier:jetifier-core:1.0.0-beta09=classpath
-com.android.tools.build.jetifier:jetifier-processor:1.0.0-beta09=classpath
-com.android.tools.build:aapt2-proto:4.1.3-6503028=classpath
-com.android.tools.build:aaptcompiler:4.1.3=classpath
-com.android.tools.build:apksig:4.1.3=classpath
-com.android.tools.build:apkzlib:4.1.3=classpath
-com.android.tools.build:builder-model:4.1.3=classpath
-com.android.tools.build:builder-test-api:4.1.3=classpath
-com.android.tools.build:builder:4.1.3=classpath
-com.android.tools.build:bundletool:0.14.0=classpath
-com.android.tools.build:gradle-api:4.1.3=classpath
-com.android.tools.build:gradle:4.1.3=classpath
-com.android.tools.build:manifest-merger:27.1.3=classpath
+androidx.databinding:databinding-common:7.3.0=classpath
+androidx.databinding:databinding-compiler-common:7.3.0=classpath
+com.android.databinding:baseLibrary:7.3.0=classpath
+com.android.tools.analytics-library:crash:30.3.0=classpath
+com.android.tools.analytics-library:protos:30.3.0=classpath
+com.android.tools.analytics-library:shared:30.3.0=classpath
+com.android.tools.analytics-library:tracker:30.3.0=classpath
+com.android.tools.build.jetifier:jetifier-core:1.0.0-beta10=classpath
+com.android.tools.build.jetifier:jetifier-processor:1.0.0-beta10=classpath
+com.android.tools.build:aapt2-proto:7.3.0-8691043=classpath
+com.android.tools.build:aaptcompiler:7.3.0=classpath
+com.android.tools.build:apksig:7.3.0=classpath
+com.android.tools.build:apkzlib:7.3.0=classpath
+com.android.tools.build:builder-model:7.3.0=classpath
+com.android.tools.build:builder-test-api:7.3.0=classpath
+com.android.tools.build:builder:7.3.0=classpath
+com.android.tools.build:bundletool:1.9.0=classpath
+com.android.tools.build:gradle-api:7.3.0=classpath
+com.android.tools.build:gradle:7.3.0=classpath
+com.android.tools.build:manifest-merger:30.3.0=classpath
com.android.tools.build:transform-api:2.0.0-deprecated-use-gradle-api=classpath
-com.android.tools.ddms:ddmlib:27.1.3=classpath
-com.android.tools.layoutlib:layoutlib-api:27.1.3=classpath
-com.android.tools.lint:lint-gradle-api:27.1.3=classpath
-com.android.tools.lint:lint-model:27.1.3=classpath
-com.android.tools:annotations:27.1.3=classpath
-com.android.tools:common:27.1.3=classpath
-com.android.tools:dvlib:27.1.3=classpath
-com.android.tools:repository:27.1.3=classpath
-com.android.tools:sdk-common:27.1.3=classpath
-com.android.tools:sdklib:27.1.3=classpath
-com.android:signflinger:4.1.3=classpath
-com.android:zipflinger:4.1.3=classpath
+com.android.tools.ddms:ddmlib:30.3.0=classpath
+com.android.tools.layoutlib:layoutlib-api:30.3.0=classpath
+com.android.tools.lint:lint-model:30.3.0=classpath
+com.android.tools.lint:lint-typedef-remover:30.3.0=classpath
+com.android.tools.utp:android-device-provider-ddmlib-proto:30.3.0=classpath
+com.android.tools.utp:android-device-provider-gradle-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-host-additional-test-output-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-host-coverage-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-host-retention-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-result-listener-gradle-proto:30.3.0=classpath
+com.android.tools:annotations:30.3.0=classpath
+com.android.tools:common:30.3.0=classpath
+com.android.tools:dvlib:30.3.0=classpath
+com.android.tools:repository:30.3.0=classpath
+com.android.tools:sdk-common:30.3.0=classpath
+com.android.tools:sdklib:30.3.0=classpath
+com.android:signflinger:7.3.0=classpath
+com.android:zipflinger:7.3.0=classpath
com.github.gundy:semver4j:0.16.4=classpath
+com.google.android:annotations:4.1.1.4=classpath
+com.google.api.grpc:proto-google-common-protos:2.0.1=classpath
com.google.auto.value:auto-value-annotations:1.6.2=classpath
com.google.code.findbugs:jsr305:3.0.2=classpath
-com.google.code.gson:gson:2.8.6=classpath
+com.google.code.gson:gson:2.8.9=classpath
com.google.crypto.tink:tink:1.3.0-rc2=classpath
-com.google.errorprone:error_prone_annotations:2.3.4=classpath
+com.google.dagger:dagger:2.28.3=classpath
+com.google.errorprone:error_prone_annotations:2.4.0=classpath
com.google.flatbuffers:flatbuffers-java:1.12.0=classpath
com.google.guava:failureaccess:1.0.1=classpath
-com.google.guava:guava:29.0-jre=classpath
+com.google.guava:guava:30.1-jre=classpath
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=classpath
com.google.j2objc:j2objc-annotations:1.3=classpath
com.google.jimfs:jimfs:1.1=classpath
-com.google.protobuf:protobuf-java-util:3.10.0=classpath
-com.google.protobuf:protobuf-java:3.10.0=classpath
-com.google.test.platform:core-proto:0.0.2-dev=classpath
+com.google.protobuf:protobuf-java-util:3.17.2=classpath
+com.google.protobuf:protobuf-java:3.17.2=classpath
+com.google.testing.platform:core-proto:0.0.8-alpha07=classpath
com.googlecode.json-simple:json-simple:1.1=classpath
com.googlecode.juniversalchardet:juniversalchardet:1.0.3=classpath
com.squareup:javapoet:1.10.0=classpath
com.squareup:javawriter:2.5.0=classpath
com.sun.activation:javax.activation:1.2.0=classpath
-com.sun.istack:istack-commons-runtime:3.0.7=classpath
-com.sun.xml.fastinfoset:FastInfoset:1.2.15=classpath
-commons-codec:commons-codec:1.10=classpath
+com.sun.istack:istack-commons-runtime:3.0.8=classpath
+com.sun.xml.fastinfoset:FastInfoset:1.2.16=classpath
+commons-codec:commons-codec:1.11=classpath
commons-io:commons-io:2.4=classpath
commons-logging:commons-logging:1.2=classpath
de.undercouch:gradle-download-task:4.1.1=classpath
-it.unimi.dsi:fastutil:7.2.0=classpath
-javax.activation:javax.activation-api:1.2.0=classpath
+io.grpc:grpc-api:1.39.0=classpath
+io.grpc:grpc-context:1.39.0=classpath
+io.grpc:grpc-core:1.39.0=classpath
+io.grpc:grpc-netty:1.39.0=classpath
+io.grpc:grpc-protobuf-lite:1.39.0=classpath
+io.grpc:grpc-protobuf:1.39.0=classpath
+io.grpc:grpc-stub:1.39.0=classpath
+io.netty:netty-buffer:4.1.52.Final=classpath
+io.netty:netty-codec-http2:4.1.52.Final=classpath
+io.netty:netty-codec-http:4.1.52.Final=classpath
+io.netty:netty-codec-socks:4.1.52.Final=classpath
+io.netty:netty-codec:4.1.52.Final=classpath
+io.netty:netty-common:4.1.52.Final=classpath
+io.netty:netty-handler-proxy:4.1.52.Final=classpath
+io.netty:netty-handler:4.1.52.Final=classpath
+io.netty:netty-resolver:4.1.52.Final=classpath
+io.netty:netty-transport:4.1.52.Final=classpath
+io.perfmark:perfmark-api:0.23.0=classpath
+it.unimi.dsi:fastutil:8.4.0=classpath
+jakarta.activation:jakarta.activation-api:1.2.1=classpath
+jakarta.xml.bind:jakarta.xml.bind-api:2.3.2=classpath
+javax.annotation:javax.annotation-api:1.3.2=classpath
javax.inject:javax.inject:1=classpath
-javax.xml.bind:jaxb-api:2.3.1=classpath
+net.java.dev.jna:jna-platform:5.6.0=classpath
+net.java.dev.jna:jna:5.6.0=classpath
net.sf.jopt-simple:jopt-simple:4.9=classpath
net.sf.kxml:kxml2:2.3.0=classpath
-net.sf.proguard:proguard-base:6.0.3=classpath
-net.sf.proguard:proguard-gradle:6.0.3=classpath
-org.antlr:antlr4:4.5.3=classpath
-org.apache.commons:commons-compress:1.12=classpath
-org.apache.httpcomponents:httpclient:4.5.6=classpath
-org.apache.httpcomponents:httpcore:4.4.10=classpath
+org.apache.commons:commons-compress:1.20=classpath
+org.apache.httpcomponents:httpclient:4.5.13=classpath
+org.apache.httpcomponents:httpcore:4.4.13=classpath
org.apache.httpcomponents:httpmime:4.5.6=classpath
-org.bouncycastle:bcpkix-jdk15on:1.56=classpath
-org.bouncycastle:bcprov-jdk15on:1.56=classpath
-org.checkerframework:checker-qual:2.11.1=classpath
-org.glassfish.jaxb:jaxb-runtime:2.3.1=classpath
-org.glassfish.jaxb:txw2:2.3.1=classpath
+org.bitbucket.b_c:jose4j:0.7.0=classpath
+org.bouncycastle:bcpkix-jdk15on:1.67=classpath
+org.bouncycastle:bcprov-jdk15on:1.67=classpath
+org.checkerframework:checker-qual:3.5.0=classpath
+org.codehaus.mojo:animal-sniffer-annotations:1.19=classpath
+org.glassfish.jaxb:jaxb-runtime:2.3.2=classpath
+org.glassfish.jaxb:txw2:2.3.2=classpath
org.jdom:jdom2:2.0.6=classpath
-org.jetbrains.intellij.deps:trove4j:1.0.20181211=classpath
-org.jetbrains.kotlin:kotlin-android-extensions:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-annotation-processing-gradle:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-build-common:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-compiler-embeddable:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-compiler-runner:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-daemon-client:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-daemon-embeddable:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-native-utils:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-project-model:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-reflect:1.3.72=classpath
-org.jetbrains.kotlin:kotlin-scripting-common:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-scripting-jvm:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-stdlib-common:1.3.72=classpath
-org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.72=classpath
-org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.72=classpath
-org.jetbrains.kotlin:kotlin-stdlib:1.3.72=classpath
-org.jetbrains.kotlin:kotlin-tooling-metadata:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-util-io:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-util-klib:1.5.31=classpath
+org.jetbrains.intellij.deps:trove4j:1.0.20200330=classpath
+org.jetbrains.kotlin:kotlin-android-extensions:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-annotation-processing-gradle:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-build-common:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-compiler-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-compiler-runner:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-daemon-client:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-daemon-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin-idea:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-native-utils:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-project-model:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-reflect:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-scripting-common:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-scripting-jvm:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-stdlib-common:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-stdlib:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-tooling-core:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-tooling-metadata:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-util-io:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-util-klib:1.7.10=classpath
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.0=classpath
-org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0=classpath
-org.jetbrains.trove4j:trove4j:20160824=classpath
org.jetbrains:annotations:13.0=classpath
org.json:json:20180813=classpath
-org.jvnet.staxex:stax-ex:1.8=classpath
-org.ow2.asm:asm-analysis:7.0=classpath
-org.ow2.asm:asm-commons:7.0=classpath
-org.ow2.asm:asm-tree:7.0=classpath
-org.ow2.asm:asm-util:7.0=classpath
-org.ow2.asm:asm:7.0=classpath
-org.tensorflow:tensorflow-lite-metadata:0.1.0-rc1=classpath
+org.jvnet.staxex:stax-ex:1.8.1=classpath
+org.ow2.asm:asm-analysis:9.1=classpath
+org.ow2.asm:asm-commons:9.1=classpath
+org.ow2.asm:asm-tree:9.1=classpath
+org.ow2.asm:asm-util:9.1=classpath
+org.ow2.asm:asm:9.1=classpath
+org.slf4j:slf4j-api:1.7.30=classpath
+org.tensorflow:tensorflow-lite-metadata:0.1.0-rc2=classpath
+xerces:xercesImpl:2.12.0=classpath
+xml-apis:xml-apis:1.4.01=classpath
empty=
diff --git a/dev/integration_tests/android_views/android/project-app.lockfile b/dev/integration_tests/android_views/android/project-app.lockfile
index ab7ba1e..04eea48 100644
--- a/dev/integration_tests/android_views/android/project-app.lockfile
+++ b/dev/integration_tests/android_views/android/project-app.lockfile
@@ -3,7 +3,8 @@
# This file is expected to be part of source control.
androidx.activity:activity:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
androidx.annotation:annotation-experimental:1.1.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
-androidx.annotation:annotation:1.2.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.annotation:annotation:1.2.0=debugAndroidTestCompileClasspath
+androidx.annotation:annotation:1.5.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
androidx.arch.core:core-common:2.1.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
androidx.arch.core:core-runtime:2.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
androidx.collection:collection:1.1.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
@@ -21,8 +22,8 @@
androidx.tracing:tracing:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
androidx.versionedparcelable:versionedparcelable:1.1.1=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
androidx.viewpager:viewpager:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
-androidx.window:window-java:1.0.0-beta03=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
-androidx.window:window:1.0.0-beta03=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.window:window-java:1.0.0-beta04=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.window:window:1.0.0-beta04=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
com.android.tools.analytics-library:protos:27.1.3=lintClassPath
com.android.tools.analytics-library:shared:27.1.3=lintClassPath
com.android.tools.analytics-library:tracker:27.1.3=lintClassPath
@@ -54,14 +55,13 @@
com.android.tools:sdklib:27.1.3=lintClassPath
com.android:signflinger:4.1.3=lintClassPath
com.android:zipflinger:4.1.3=lintClassPath
-com.google.code.findbugs:jsr305:3.0.2=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,lintClassPath,profileRuntimeClasspath,profileUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath
+com.google.code.findbugs:jsr305:3.0.2=lintClassPath
com.google.code.gson:gson:2.8.5=lintClassPath
-com.google.errorprone:error_prone_annotations:2.3.2=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,lintClassPath,profileRuntimeClasspath,profileUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath
-com.google.guava:failureaccess:1.0.1=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,lintClassPath,profileRuntimeClasspath,profileUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath
-com.google.guava:guava:28.1-android=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,profileRuntimeClasspath,profileUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath
+com.google.errorprone:error_prone_annotations:2.3.2=lintClassPath
+com.google.guava:failureaccess:1.0.1=lintClassPath
com.google.guava:guava:28.1-jre=lintClassPath
-com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,lintClassPath,profileRuntimeClasspath,profileUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath
-com.google.j2objc:j2objc-annotations:1.3=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,lintClassPath,profileRuntimeClasspath,profileUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath
+com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=lintClassPath
+com.google.j2objc:j2objc-annotations:1.3=lintClassPath
com.google.jimfs:jimfs:1.1=lintClassPath
com.google.protobuf:protobuf-java:3.10.0=lintClassPath
com.googlecode.json-simple:json-simple:1.1=lintClassPath
@@ -83,21 +83,26 @@
org.apache.httpcomponents:httpmime:4.5.6=lintClassPath
org.bouncycastle:bcpkix-jdk15on:1.56=lintClassPath
org.bouncycastle:bcprov-jdk15on:1.56=lintClassPath
-org.checkerframework:checker-compat-qual:2.5.5=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,profileRuntimeClasspath,profileUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath
org.checkerframework:checker-qual:2.8.1=lintClassPath
org.codehaus.groovy:groovy-all:2.4.15=lintClassPath
-org.codehaus.mojo:animal-sniffer-annotations:1.18=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,lintClassPath,profileRuntimeClasspath,profileUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath
+org.codehaus.mojo:animal-sniffer-annotations:1.18=lintClassPath
org.glassfish.jaxb:jaxb-runtime:2.3.1=lintClassPath
org.glassfish.jaxb:txw2:2.3.1=lintClassPath
+org.jacoco:org.jacoco.agent:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.ant:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.core:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.report:0.8.7=androidJacocoAnt
org.jetbrains.kotlin:kotlin-reflect:1.3.72=lintClassPath
org.jetbrains.kotlin:kotlin-stdlib-common:1.3.72=lintClassPath
-org.jetbrains.kotlin:kotlin-stdlib-common:1.5.31=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlin:kotlin-stdlib-common:1.5.31=debugAndroidTestCompileClasspath
+org.jetbrains.kotlin:kotlin-stdlib-common:1.7.10=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.72=lintClassPath
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.5.30=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.72=lintClassPath
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.30=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.jetbrains.kotlin:kotlin-stdlib:1.3.72=lintClassPath
-org.jetbrains.kotlin:kotlin-stdlib:1.5.31=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlin:kotlin-stdlib:1.5.31=debugAndroidTestCompileClasspath
+org.jetbrains.kotlin:kotlin-stdlib:1.7.10=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.2=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
@@ -105,8 +110,12 @@
org.jetbrains:annotations:13.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,lintClassPath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.jvnet.staxex:stax-ex:1.8=lintClassPath
org.ow2.asm:asm-analysis:7.0=lintClassPath
+org.ow2.asm:asm-analysis:9.1=androidJacocoAnt
org.ow2.asm:asm-commons:7.0=lintClassPath
+org.ow2.asm:asm-commons:9.1=androidJacocoAnt
org.ow2.asm:asm-tree:7.0=lintClassPath
+org.ow2.asm:asm-tree:9.1=androidJacocoAnt
org.ow2.asm:asm-util:7.0=lintClassPath
org.ow2.asm:asm:7.0=lintClassPath
-empty=androidApis,androidTestUtil,compile,coreLibraryDesugaring,debugAndroidTestAnnotationProcessorClasspath,debugAndroidTestRuntimeClasspath,debugAnnotationProcessorClasspath,debugReverseMetadataValues,debugUnitTestAnnotationProcessorClasspath,debugWearBundling,lintChecks,lintPublish,profileAnnotationProcessorClasspath,profileReverseMetadataValues,profileUnitTestAnnotationProcessorClasspath,profileWearBundling,releaseAnnotationProcessorClasspath,releaseReverseMetadataValues,releaseUnitTestAnnotationProcessorClasspath,releaseWearBundling,testCompile
+org.ow2.asm:asm:9.1=androidJacocoAnt
+empty=androidApis,androidJdkImage,androidTestUtil,compile,coreLibraryDesugaring,debugAndroidTestAnnotationProcessorClasspath,debugAndroidTestRuntimeClasspath,debugAnnotationProcessorClasspath,debugReverseMetadataValues,debugUnitTestAnnotationProcessorClasspath,debugWearBundling,lintChecks,lintPublish,profileAnnotationProcessorClasspath,profileReverseMetadataValues,profileUnitTestAnnotationProcessorClasspath,profileWearBundling,releaseAnnotationProcessorClasspath,releaseReverseMetadataValues,releaseUnitTestAnnotationProcessorClasspath,releaseWearBundling,testCompile
diff --git a/dev/integration_tests/android_views/android/project-path_provider_android.lockfile b/dev/integration_tests/android_views/android/project-path_provider_android.lockfile
new file mode 100644
index 0000000..212a16c
--- /dev/null
+++ b/dev/integration_tests/android_views/android/project-path_provider_android.lockfile
@@ -0,0 +1,120 @@
+# This is a Gradle generated file for dependency locking.
+# Manual edits can break the build and are not advised.
+# This file is expected to be part of source control.
+androidx.activity:activity:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.annotation:annotation-experimental:1.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.annotation:annotation:1.5.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.arch.core:core-common:2.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.arch.core:core-runtime:2.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.collection:collection:1.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.core:core:1.6.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.customview:customview:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.fragment:fragment:1.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.lifecycle:lifecycle-common-java8:2.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.lifecycle:lifecycle-common:2.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.lifecycle:lifecycle-livedata-core:2.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.lifecycle:lifecycle-livedata:2.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.lifecycle:lifecycle-runtime:2.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.lifecycle:lifecycle-viewmodel:2.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.loader:loader:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.savedstate:savedstate:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.tracing:tracing:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.versionedparcelable:versionedparcelable:1.1.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.viewpager:viewpager:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.window:window-java:1.0.0-beta04=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.window:window:1.0.0-beta04=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+com.android.tools.analytics-library:protos:27.1.3=lintClassPath
+com.android.tools.analytics-library:shared:27.1.3=lintClassPath
+com.android.tools.analytics-library:tracker:27.1.3=lintClassPath
+com.android.tools.build:aapt2-proto:4.1.0-alpha01-6193524=lintClassPath
+com.android.tools.build:aapt2:4.1.3-6503028=_internal_aapt2_binary
+com.android.tools.build:apksig:4.1.3=lintClassPath
+com.android.tools.build:apkzlib:4.1.3=lintClassPath
+com.android.tools.build:builder-model:4.1.3=lintClassPath
+com.android.tools.build:builder-test-api:4.1.3=lintClassPath
+com.android.tools.build:builder:4.1.3=lintClassPath
+com.android.tools.build:gradle-api:4.1.3=lintClassPath
+com.android.tools.build:manifest-merger:27.1.3=lintClassPath
+com.android.tools.ddms:ddmlib:27.1.3=lintClassPath
+com.android.tools.external.com-intellij:intellij-core:27.1.3=lintClassPath
+com.android.tools.external.com-intellij:kotlin-compiler:27.1.3=lintClassPath
+com.android.tools.external.org-jetbrains:uast:27.1.3=lintClassPath
+com.android.tools.layoutlib:layoutlib-api:27.1.3=lintClassPath
+com.android.tools.lint:lint-api:27.1.3=lintClassPath
+com.android.tools.lint:lint-checks:27.1.3=lintClassPath
+com.android.tools.lint:lint-gradle-api:27.1.3=lintClassPath
+com.android.tools.lint:lint-gradle:27.1.3=lintClassPath
+com.android.tools.lint:lint-model:27.1.3=lintClassPath
+com.android.tools.lint:lint:27.1.3=lintClassPath
+com.android.tools:annotations:27.1.3=lintClassPath
+com.android.tools:common:27.1.3=lintClassPath
+com.android.tools:dvlib:27.1.3=lintClassPath
+com.android.tools:repository:27.1.3=lintClassPath
+com.android.tools:sdk-common:27.1.3=lintClassPath
+com.android.tools:sdklib:27.1.3=lintClassPath
+com.android:signflinger:4.1.3=lintClassPath
+com.android:zipflinger:4.1.3=lintClassPath
+com.google.code.findbugs:jsr305:3.0.2=lintClassPath
+com.google.code.gson:gson:2.8.5=lintClassPath
+com.google.errorprone:error_prone_annotations:2.3.2=lintClassPath
+com.google.guava:failureaccess:1.0.1=lintClassPath
+com.google.guava:guava:28.1-jre=lintClassPath
+com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=lintClassPath
+com.google.j2objc:j2objc-annotations:1.3=lintClassPath
+com.google.jimfs:jimfs:1.1=lintClassPath
+com.google.protobuf:protobuf-java:3.10.0=lintClassPath
+com.googlecode.json-simple:json-simple:1.1=lintClassPath
+com.squareup:javawriter:2.5.0=lintClassPath
+com.sun.activation:javax.activation:1.2.0=lintClassPath
+com.sun.istack:istack-commons-runtime:3.0.7=lintClassPath
+com.sun.xml.fastinfoset:FastInfoset:1.2.15=lintClassPath
+commons-codec:commons-codec:1.10=lintClassPath
+commons-logging:commons-logging:1.2=lintClassPath
+it.unimi.dsi:fastutil:7.2.0=lintClassPath
+javax.activation:javax.activation-api:1.2.0=lintClassPath
+javax.inject:javax.inject:1=lintClassPath
+javax.xml.bind:jaxb-api:2.3.1=lintClassPath
+junit:junit:4.13.2=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+net.sf.jopt-simple:jopt-simple:4.9=lintClassPath
+net.sf.kxml:kxml2:2.3.0=lintClassPath
+org.apache.commons:commons-compress:1.12=lintClassPath
+org.apache.httpcomponents:httpclient:4.5.6=lintClassPath
+org.apache.httpcomponents:httpcore:4.4.10=lintClassPath
+org.apache.httpcomponents:httpmime:4.5.6=lintClassPath
+org.bouncycastle:bcpkix-jdk15on:1.56=lintClassPath
+org.bouncycastle:bcprov-jdk15on:1.56=lintClassPath
+org.checkerframework:checker-qual:2.8.1=lintClassPath
+org.codehaus.groovy:groovy-all:2.4.15=lintClassPath
+org.codehaus.mojo:animal-sniffer-annotations:1.18=lintClassPath
+org.glassfish.jaxb:jaxb-runtime:2.3.1=lintClassPath
+org.glassfish.jaxb:txw2:2.3.1=lintClassPath
+org.hamcrest:hamcrest-core:1.3=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jacoco:org.jacoco.agent:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.ant:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.core:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.report:0.8.7=androidJacocoAnt
+org.jetbrains.kotlin:kotlin-reflect:1.3.72=lintClassPath
+org.jetbrains.kotlin:kotlin-stdlib-common:1.3.72=lintClassPath
+org.jetbrains.kotlin:kotlin-stdlib-common:1.7.10=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.72=lintClassPath
+org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.5.30=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.72=lintClassPath
+org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.30=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlin:kotlin-stdlib:1.3.72=lintClassPath
+org.jetbrains.kotlin:kotlin-stdlib:1.7.10=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.trove4j:trove4j:20160824=lintClassPath
+org.jetbrains:annotations:13.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,lintClassPath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jvnet.staxex:stax-ex:1.8=lintClassPath
+org.ow2.asm:asm-analysis:7.0=lintClassPath
+org.ow2.asm:asm-analysis:9.1=androidJacocoAnt
+org.ow2.asm:asm-commons:7.0=lintClassPath
+org.ow2.asm:asm-commons:9.1=androidJacocoAnt
+org.ow2.asm:asm-tree:7.0=lintClassPath
+org.ow2.asm:asm-tree:9.1=androidJacocoAnt
+org.ow2.asm:asm-util:7.0=lintClassPath
+org.ow2.asm:asm:7.0=lintClassPath
+org.ow2.asm:asm:9.1=androidJacocoAnt
+empty=androidApis,androidJdkImage,androidTestUtil,compile,coreLibraryDesugaring,debugAndroidTestAnnotationProcessorClasspath,debugAnnotationProcessorClasspath,debugUnitTestAnnotationProcessorClasspath,lintChecks,lintPublish,profileAnnotationProcessorClasspath,profileUnitTestAnnotationProcessorClasspath,releaseAnnotationProcessorClasspath,releaseUnitTestAnnotationProcessorClasspath,testCompile
diff --git a/dev/integration_tests/android_views/android/settings.gradle b/dev/integration_tests/android_views/android/settings.gradle
index 03ae72d..a020595 100644
--- a/dev/integration_tests/android_views/android/settings.gradle
+++ b/dev/integration_tests/android_views/android/settings.gradle
@@ -8,8 +8,6 @@
include ':app'
-enableFeaturePreview('ONE_LOCKFILE_PER_PROJECT')
-
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()
diff --git a/dev/integration_tests/android_views/pubspec.yaml b/dev/integration_tests/android_views/pubspec.yaml
index 04289ad..db69bfb 100644
--- a/dev/integration_tests/android_views/pubspec.yaml
+++ b/dev/integration_tests/android_views/pubspec.yaml
@@ -14,7 +14,7 @@
path_provider: 2.0.15
# This made non-transitive to allow exact pinning
# https://github.com/flutter/flutter/issues/116376
- path_provider_android: 2.0.21
+ path_provider_android: 2.0.27
collection: 1.17.2
assets_for_android_views:
git:
@@ -27,7 +27,6 @@
characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
ffi: 2.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
file: 6.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
matcher: 0.12.16 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.9.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -40,36 +39,39 @@
plugin_platform_interface: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
process: 4.2.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
sync_http: 0.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- vm_service: 11.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ vm_service: 11.7.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- win32: 5.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ win32: 5.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
xdg_directories: 1.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
flutter_test:
sdk: flutter
- test: 1.24.3
+ test: 1.24.4
- _fe_analyzer_shared: 61.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- analyzer: 5.13.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ _fe_analyzer_shared: 62.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ analyzer: 6.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
args: 2.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
clock: 1.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
convert: 3.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
coverage: 1.6.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
crypto: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ dart_internal: 0.2.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
fake_async: 1.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
frontend_server_client: 3.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
glob: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http_multi_server: 3.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http_parser: 4.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
io: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
logging: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
mime: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
node_preamble: 2.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -82,7 +84,7 @@
shelf_web_socket: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_map_stack_trace: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_maps: 0.10.12 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_core: 0.5.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_core: 0.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -92,4 +94,4 @@
flutter:
uses-material-design: true
-# PUBSPEC CHECKSUM: 8c17
+# PUBSPEC CHECKSUM: ae09
diff --git a/dev/integration_tests/channels/android/build.gradle b/dev/integration_tests/channels/android/build.gradle
index d93b7eb..a2a8866 100644
--- a/dev/integration_tests/channels/android/build.gradle
+++ b/dev/integration_tests/channels/android/build.gradle
@@ -2,6 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// This file is auto generated.
+// To update all the build.gradle files in the Flutter repo,
+// See dev/tools/bin/generate_gradle_lockfiles.dart.
+
buildscript {
ext.kotlin_version = '1.7.10'
repositories {
@@ -13,6 +17,10 @@
classpath 'com.android.tools.build:gradle:7.3.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
+
+ configurations.classpath {
+ resolutionStrategy.activateDependencyLocking()
+ }
}
allprojects {
@@ -23,11 +31,19 @@
}
rootProject.buildDir = '../build'
+
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
project.evaluationDependsOn(':app')
+ dependencyLocking {
+ ignoredDependencies.add('io.flutter:*')
+ lockFile = file("${rootProject.projectDir}/project-${project.name}.lockfile")
+ if (!project.hasProperty('local-engine-repo')) {
+ lockAllConfigurations()
+ }
+ }
}
tasks.register("clean", Delete) {
diff --git a/dev/integration_tests/channels/android/buildscript-gradle.lockfile b/dev/integration_tests/channels/android/buildscript-gradle.lockfile
new file mode 100644
index 0000000..eb60580
--- /dev/null
+++ b/dev/integration_tests/channels/android/buildscript-gradle.lockfile
@@ -0,0 +1,152 @@
+# This is a Gradle generated file for dependency locking.
+# Manual edits can break the build and are not advised.
+# This file is expected to be part of source control.
+androidx.databinding:databinding-common:7.3.0=classpath
+androidx.databinding:databinding-compiler-common:7.3.0=classpath
+com.android.databinding:baseLibrary:7.3.0=classpath
+com.android.tools.analytics-library:crash:30.3.0=classpath
+com.android.tools.analytics-library:protos:30.3.0=classpath
+com.android.tools.analytics-library:shared:30.3.0=classpath
+com.android.tools.analytics-library:tracker:30.3.0=classpath
+com.android.tools.build.jetifier:jetifier-core:1.0.0-beta10=classpath
+com.android.tools.build.jetifier:jetifier-processor:1.0.0-beta10=classpath
+com.android.tools.build:aapt2-proto:7.3.0-8691043=classpath
+com.android.tools.build:aaptcompiler:7.3.0=classpath
+com.android.tools.build:apksig:7.3.0=classpath
+com.android.tools.build:apkzlib:7.3.0=classpath
+com.android.tools.build:builder-model:7.3.0=classpath
+com.android.tools.build:builder-test-api:7.3.0=classpath
+com.android.tools.build:builder:7.3.0=classpath
+com.android.tools.build:bundletool:1.9.0=classpath
+com.android.tools.build:gradle-api:7.3.0=classpath
+com.android.tools.build:gradle:7.3.0=classpath
+com.android.tools.build:manifest-merger:30.3.0=classpath
+com.android.tools.build:transform-api:2.0.0-deprecated-use-gradle-api=classpath
+com.android.tools.ddms:ddmlib:30.3.0=classpath
+com.android.tools.layoutlib:layoutlib-api:30.3.0=classpath
+com.android.tools.lint:lint-model:30.3.0=classpath
+com.android.tools.lint:lint-typedef-remover:30.3.0=classpath
+com.android.tools.utp:android-device-provider-ddmlib-proto:30.3.0=classpath
+com.android.tools.utp:android-device-provider-gradle-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-host-additional-test-output-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-host-coverage-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-host-retention-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-result-listener-gradle-proto:30.3.0=classpath
+com.android.tools:annotations:30.3.0=classpath
+com.android.tools:common:30.3.0=classpath
+com.android.tools:dvlib:30.3.0=classpath
+com.android.tools:repository:30.3.0=classpath
+com.android.tools:sdk-common:30.3.0=classpath
+com.android.tools:sdklib:30.3.0=classpath
+com.android:signflinger:7.3.0=classpath
+com.android:zipflinger:7.3.0=classpath
+com.github.gundy:semver4j:0.16.4=classpath
+com.google.android:annotations:4.1.1.4=classpath
+com.google.api.grpc:proto-google-common-protos:2.0.1=classpath
+com.google.auto.value:auto-value-annotations:1.6.2=classpath
+com.google.code.findbugs:jsr305:3.0.2=classpath
+com.google.code.gson:gson:2.8.9=classpath
+com.google.crypto.tink:tink:1.3.0-rc2=classpath
+com.google.dagger:dagger:2.28.3=classpath
+com.google.errorprone:error_prone_annotations:2.4.0=classpath
+com.google.flatbuffers:flatbuffers-java:1.12.0=classpath
+com.google.guava:failureaccess:1.0.1=classpath
+com.google.guava:guava:30.1-jre=classpath
+com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=classpath
+com.google.j2objc:j2objc-annotations:1.3=classpath
+com.google.jimfs:jimfs:1.1=classpath
+com.google.protobuf:protobuf-java-util:3.17.2=classpath
+com.google.protobuf:protobuf-java:3.17.2=classpath
+com.google.testing.platform:core-proto:0.0.8-alpha07=classpath
+com.googlecode.json-simple:json-simple:1.1=classpath
+com.googlecode.juniversalchardet:juniversalchardet:1.0.3=classpath
+com.squareup:javapoet:1.10.0=classpath
+com.squareup:javawriter:2.5.0=classpath
+com.sun.activation:javax.activation:1.2.0=classpath
+com.sun.istack:istack-commons-runtime:3.0.8=classpath
+com.sun.xml.fastinfoset:FastInfoset:1.2.16=classpath
+commons-codec:commons-codec:1.11=classpath
+commons-io:commons-io:2.4=classpath
+commons-logging:commons-logging:1.2=classpath
+de.undercouch:gradle-download-task:4.1.1=classpath
+io.grpc:grpc-api:1.39.0=classpath
+io.grpc:grpc-context:1.39.0=classpath
+io.grpc:grpc-core:1.39.0=classpath
+io.grpc:grpc-netty:1.39.0=classpath
+io.grpc:grpc-protobuf-lite:1.39.0=classpath
+io.grpc:grpc-protobuf:1.39.0=classpath
+io.grpc:grpc-stub:1.39.0=classpath
+io.netty:netty-buffer:4.1.52.Final=classpath
+io.netty:netty-codec-http2:4.1.52.Final=classpath
+io.netty:netty-codec-http:4.1.52.Final=classpath
+io.netty:netty-codec-socks:4.1.52.Final=classpath
+io.netty:netty-codec:4.1.52.Final=classpath
+io.netty:netty-common:4.1.52.Final=classpath
+io.netty:netty-handler-proxy:4.1.52.Final=classpath
+io.netty:netty-handler:4.1.52.Final=classpath
+io.netty:netty-resolver:4.1.52.Final=classpath
+io.netty:netty-transport:4.1.52.Final=classpath
+io.perfmark:perfmark-api:0.23.0=classpath
+it.unimi.dsi:fastutil:8.4.0=classpath
+jakarta.activation:jakarta.activation-api:1.2.1=classpath
+jakarta.xml.bind:jakarta.xml.bind-api:2.3.2=classpath
+javax.annotation:javax.annotation-api:1.3.2=classpath
+javax.inject:javax.inject:1=classpath
+net.java.dev.jna:jna-platform:5.6.0=classpath
+net.java.dev.jna:jna:5.6.0=classpath
+net.sf.jopt-simple:jopt-simple:4.9=classpath
+net.sf.kxml:kxml2:2.3.0=classpath
+org.apache.commons:commons-compress:1.20=classpath
+org.apache.httpcomponents:httpclient:4.5.13=classpath
+org.apache.httpcomponents:httpcore:4.4.13=classpath
+org.apache.httpcomponents:httpmime:4.5.6=classpath
+org.bitbucket.b_c:jose4j:0.7.0=classpath
+org.bouncycastle:bcpkix-jdk15on:1.67=classpath
+org.bouncycastle:bcprov-jdk15on:1.67=classpath
+org.checkerframework:checker-qual:3.5.0=classpath
+org.codehaus.mojo:animal-sniffer-annotations:1.19=classpath
+org.glassfish.jaxb:jaxb-runtime:2.3.2=classpath
+org.glassfish.jaxb:txw2:2.3.2=classpath
+org.jdom:jdom2:2.0.6=classpath
+org.jetbrains.intellij.deps:trove4j:1.0.20200330=classpath
+org.jetbrains.kotlin:kotlin-android-extensions:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-annotation-processing-gradle:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-build-common:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-compiler-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-compiler-runner:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-daemon-client:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-daemon-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin-idea:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-native-utils:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-project-model:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-reflect:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-scripting-common:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-scripting-jvm:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-stdlib-common:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-stdlib:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-tooling-core:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-tooling-metadata:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-util-io:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-util-klib:1.7.10=classpath
+org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.0=classpath
+org.jetbrains:annotations:13.0=classpath
+org.json:json:20180813=classpath
+org.jvnet.staxex:stax-ex:1.8.1=classpath
+org.ow2.asm:asm-analysis:9.1=classpath
+org.ow2.asm:asm-commons:9.1=classpath
+org.ow2.asm:asm-tree:9.1=classpath
+org.ow2.asm:asm-util:9.1=classpath
+org.ow2.asm:asm:9.1=classpath
+org.slf4j:slf4j-api:1.7.30=classpath
+org.tensorflow:tensorflow-lite-metadata:0.1.0-rc2=classpath
+xerces:xercesImpl:2.12.0=classpath
+xml-apis:xml-apis:1.4.01=classpath
+empty=
diff --git a/dev/integration_tests/channels/android/project-app.lockfile b/dev/integration_tests/channels/android/project-app.lockfile
new file mode 100644
index 0000000..eedf713
--- /dev/null
+++ b/dev/integration_tests/channels/android/project-app.lockfile
@@ -0,0 +1,70 @@
+# This is a Gradle generated file for dependency locking.
+# Manual edits can break the build and are not advised.
+# This file is expected to be part of source control.
+androidx.activity:activity:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.annotation:annotation-experimental:1.1.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.annotation:annotation:1.2.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.arch.core:core-common:2.1.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.arch.core:core-runtime:2.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.collection:collection:1.1.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.core:core:1.6.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.customview:customview:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.fragment:fragment:1.1.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.lifecycle:lifecycle-common-java8:2.2.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.lifecycle:lifecycle-common:2.2.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.lifecycle:lifecycle-livedata-core:2.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.lifecycle:lifecycle-livedata:2.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.lifecycle:lifecycle-runtime:2.2.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.lifecycle:lifecycle-viewmodel:2.1.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.loader:loader:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.savedstate:savedstate:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.test.espresso:espresso-core:3.2.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.test.espresso:espresso-idling-resource:3.2.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.test:monitor:1.2.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.test:rules:1.2.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.test:runner:1.2.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.tracing:tracing:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.versionedparcelable:versionedparcelable:1.1.1=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.viewpager:viewpager:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.window:window-java:1.0.0-beta04=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.window:window:1.0.0-beta04=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+com.google.code.findbugs:jsr305:2.0.1=debugAndroidTestCompileClasspath
+com.google.code.findbugs:jsr305:3.0.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+com.google.errorprone:error_prone_annotations:2.3.2=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,profileRuntimeClasspath,profileUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath
+com.google.guava:failureaccess:1.0.1=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,profileRuntimeClasspath,profileUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath
+com.google.guava:guava:28.1-android=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,profileRuntimeClasspath,profileUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath
+com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,profileRuntimeClasspath,profileUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath
+com.google.j2objc:j2objc-annotations:1.3=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,profileRuntimeClasspath,profileUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath
+com.squareup:javawriter:2.1.1=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+javax.inject:javax.inject:1=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+junit:junit:4.12=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+net.java.dev.jna:jna:5.6.0=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
+net.sf.kxml:kxml2:2.3.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.checkerframework:checker-compat-qual:2.5.5=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,profileRuntimeClasspath,profileUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath
+org.codehaus.mojo:animal-sniffer-annotations:1.18=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,profileRuntimeClasspath,profileUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath
+org.hamcrest:hamcrest-core:1.3=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.hamcrest:hamcrest-integration:1.3=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.hamcrest:hamcrest-library:1.3=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jacoco:org.jacoco.agent:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.ant:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.core:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.report:0.8.7=androidJacocoAnt
+org.jetbrains.intellij.deps:trove4j:1.0.20200330=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
+org.jetbrains.kotlin:kotlin-compiler-embeddable:1.7.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
+org.jetbrains.kotlin:kotlin-daemon-embeddable:1.7.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
+org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:1.7.10=kotlinKlibCommonizerClasspath
+org.jetbrains.kotlin:kotlin-reflect:1.7.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
+org.jetbrains.kotlin:kotlin-script-runtime:1.7.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
+org.jetbrains.kotlin:kotlin-stdlib-common:1.7.10=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.10=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.10=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlin:kotlin-stdlib:1.7.10=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.2=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains:annotations:13.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.ow2.asm:asm-analysis:9.1=androidJacocoAnt
+org.ow2.asm:asm-commons:9.1=androidJacocoAnt
+org.ow2.asm:asm-tree:9.1=androidJacocoAnt
+org.ow2.asm:asm:9.1=androidJacocoAnt
+empty=androidApis,androidJdkImage,androidTestApiDependenciesMetadata,androidTestCompileOnlyDependenciesMetadata,androidTestDebugApiDependenciesMetadata,androidTestDebugCompileOnlyDependenciesMetadata,androidTestDebugImplementationDependenciesMetadata,androidTestDebugIntransitiveDependenciesMetadata,androidTestDebugRuntimeOnlyDependenciesMetadata,androidTestImplementationDependenciesMetadata,androidTestIntransitiveDependenciesMetadata,androidTestProfileApiDependenciesMetadata,androidTestProfileCompileOnlyDependenciesMetadata,androidTestProfileImplementationDependenciesMetadata,androidTestProfileIntransitiveDependenciesMetadata,androidTestProfileRuntimeOnlyDependenciesMetadata,androidTestReleaseApiDependenciesMetadata,androidTestReleaseCompileOnlyDependenciesMetadata,androidTestReleaseImplementationDependenciesMetadata,androidTestReleaseIntransitiveDependenciesMetadata,androidTestReleaseRuntimeOnlyDependenciesMetadata,androidTestRuntimeOnlyDependenciesMetadata,androidTestUtil,compileOnlyDependenciesMetadata,coreLibraryDesugaring,debugAndroidTestAnnotationProcessorClasspath,debugAndroidTestApiDependenciesMetadata,debugAndroidTestCompileOnlyDependenciesMetadata,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestIntransitiveDependenciesMetadata,debugAndroidTestRuntimeClasspath,debugAndroidTestRuntimeOnlyDependenciesMetadata,debugAnnotationProcessorClasspath,debugCompileOnlyDependenciesMetadata,debugIntransitiveDependenciesMetadata,debugReverseMetadataValues,debugRuntimeOnlyDependenciesMetadata,debugUnitTestAnnotationProcessorClasspath,debugUnitTestApiDependenciesMetadata,debugUnitTestCompileOnlyDependenciesMetadata,debugUnitTestImplementationDependenciesMetadata,debugUnitTestIntransitiveDependenciesMetadata,debugUnitTestRuntimeOnlyDependenciesMetadata,debugWearBundling,intransitiveDependenciesMetadata,kotlinCompilerPluginClasspath,kotlinCompilerPluginClasspathDebug,kotlinCompilerPluginClasspathDebugAndroidTest,kotlinCompilerPluginClasspathDebugUnitTest,kotlinCompilerPluginClasspathProfile,kotlinCompilerPluginClasspathProfileUnitTest,kotlinCompilerPluginClasspathRelease,kotlinCompilerPluginClasspathReleaseUnitTest,kotlinNativeCompilerPluginClasspath,lintChecks,lintPublish,profileAnnotationProcessorClasspath,profileCompileOnlyDependenciesMetadata,profileIntransitiveDependenciesMetadata,profileReverseMetadataValues,profileRuntimeOnlyDependenciesMetadata,profileUnitTestAnnotationProcessorClasspath,profileUnitTestApiDependenciesMetadata,profileUnitTestCompileOnlyDependenciesMetadata,profileUnitTestImplementationDependenciesMetadata,profileUnitTestIntransitiveDependenciesMetadata,profileUnitTestRuntimeOnlyDependenciesMetadata,profileWearBundling,releaseAnnotationProcessorClasspath,releaseCompileOnlyDependenciesMetadata,releaseIntransitiveDependenciesMetadata,releaseReverseMetadataValues,releaseRuntimeOnlyDependenciesMetadata,releaseUnitTestAnnotationProcessorClasspath,releaseUnitTestApiDependenciesMetadata,releaseUnitTestCompileOnlyDependenciesMetadata,releaseUnitTestImplementationDependenciesMetadata,releaseUnitTestIntransitiveDependenciesMetadata,releaseUnitTestRuntimeOnlyDependenciesMetadata,releaseWearBundling,runtimeOnlyDependenciesMetadata,testApiDependenciesMetadata,testCompileOnlyDependenciesMetadata,testDebugApiDependenciesMetadata,testDebugCompileOnlyDependenciesMetadata,testDebugImplementationDependenciesMetadata,testDebugIntransitiveDependenciesMetadata,testDebugRuntimeOnlyDependenciesMetadata,testFixturesApiDependenciesMetadata,testFixturesCompileOnlyDependenciesMetadata,testFixturesDebugApiDependenciesMetadata,testFixturesDebugCompileOnlyDependenciesMetadata,testFixturesDebugImplementationDependenciesMetadata,testFixturesDebugIntransitiveDependenciesMetadata,testFixturesDebugRuntimeOnlyDependenciesMetadata,testFixturesImplementationDependenciesMetadata,testFixturesIntransitiveDependenciesMetadata,testFixturesProfileApiDependenciesMetadata,testFixturesProfileCompileOnlyDependenciesMetadata,testFixturesProfileImplementationDependenciesMetadata,testFixturesProfileIntransitiveDependenciesMetadata,testFixturesProfileRuntimeOnlyDependenciesMetadata,testFixturesReleaseApiDependenciesMetadata,testFixturesReleaseCompileOnlyDependenciesMetadata,testFixturesReleaseImplementationDependenciesMetadata,testFixturesReleaseIntransitiveDependenciesMetadata,testFixturesReleaseRuntimeOnlyDependenciesMetadata,testFixturesRuntimeOnlyDependenciesMetadata,testImplementationDependenciesMetadata,testIntransitiveDependenciesMetadata,testProfileApiDependenciesMetadata,testProfileCompileOnlyDependenciesMetadata,testProfileImplementationDependenciesMetadata,testProfileIntransitiveDependenciesMetadata,testProfileRuntimeOnlyDependenciesMetadata,testReleaseApiDependenciesMetadata,testReleaseCompileOnlyDependenciesMetadata,testReleaseImplementationDependenciesMetadata,testReleaseIntransitiveDependenciesMetadata,testReleaseRuntimeOnlyDependenciesMetadata,testRuntimeOnlyDependenciesMetadata
diff --git a/dev/integration_tests/channels/android/project-integration_test.lockfile b/dev/integration_tests/channels/android/project-integration_test.lockfile
new file mode 100644
index 0000000..f45da3d
--- /dev/null
+++ b/dev/integration_tests/channels/android/project-integration_test.lockfile
@@ -0,0 +1,62 @@
+# This is a Gradle generated file for dependency locking.
+# Manual edits can break the build and are not advised.
+# This file is expected to be part of source control.
+androidx.activity:activity:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.annotation:annotation-experimental:1.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.annotation:annotation:1.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.arch.core:core-common:2.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.arch.core:core-runtime:2.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.collection:collection:1.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.core:core:1.6.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.customview:customview:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.fragment:fragment:1.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.lifecycle:lifecycle-common-java8:2.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.lifecycle:lifecycle-common:2.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.lifecycle:lifecycle-livedata-core:2.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.lifecycle:lifecycle-livedata:2.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.lifecycle:lifecycle-runtime:2.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.lifecycle:lifecycle-viewmodel:2.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.loader:loader:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.savedstate:savedstate:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.test.espresso:espresso-core:3.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.test.espresso:espresso-idling-resource:3.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.test:monitor:1.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.test:rules:1.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.test:runner:1.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.tracing:tracing:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.versionedparcelable:versionedparcelable:1.1.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.viewpager:viewpager:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.window:window-java:1.0.0-beta04=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.window:window:1.0.0-beta04=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+com.google.code.findbugs:jsr305:3.0.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+com.google.errorprone:error_prone_annotations:2.3.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+com.google.guava:failureaccess:1.0.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+com.google.guava:guava:28.1-android=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+com.google.j2objc:j2objc-annotations:1.3=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+com.squareup:javawriter:2.1.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+javax.inject:javax.inject:1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+junit:junit:4.12=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+net.sf.kxml:kxml2:2.3.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.checkerframework:checker-compat-qual:2.5.5=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.codehaus.mojo:animal-sniffer-annotations:1.18=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.hamcrest:hamcrest-core:1.3=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.hamcrest:hamcrest-integration:1.3=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.hamcrest:hamcrest-library:1.3=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jacoco:org.jacoco.agent:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.ant:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.core:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.report:0.8.7=androidJacocoAnt
+org.jetbrains.kotlin:kotlin-stdlib-common:1.5.31=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.5.30=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.30=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlin:kotlin-stdlib:1.5.31=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains:annotations:13.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.ow2.asm:asm-analysis:9.1=androidJacocoAnt
+org.ow2.asm:asm-commons:9.1=androidJacocoAnt
+org.ow2.asm:asm-tree:9.1=androidJacocoAnt
+org.ow2.asm:asm:9.1=androidJacocoAnt
+empty=androidApis,androidJdkImage,androidTestUtil,coreLibraryDesugaring,debugAndroidTestAnnotationProcessorClasspath,debugAnnotationProcessorClasspath,debugUnitTestAnnotationProcessorClasspath,lintChecks,lintPublish,profileAnnotationProcessorClasspath,profileUnitTestAnnotationProcessorClasspath,releaseAnnotationProcessorClasspath,releaseUnitTestAnnotationProcessorClasspath
diff --git a/dev/integration_tests/channels/android/settings.gradle b/dev/integration_tests/channels/android/settings.gradle
index d3b6a40..a020595 100644
--- a/dev/integration_tests/channels/android/settings.gradle
+++ b/dev/integration_tests/channels/android/settings.gradle
@@ -2,6 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// This file is auto generated.
+// To update all the settings.gradle files in the Flutter repo,
+// See dev/tools/bin/generate_gradle_lockfiles.dart.
+
include ':app'
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
diff --git a/dev/integration_tests/channels/ios/Runner/Info.plist b/dev/integration_tests/channels/ios/Runner/Info.plist
index eb05d07..8ed5e81 100644
--- a/dev/integration_tests/channels/ios/Runner/Info.plist
+++ b/dev/integration_tests/channels/ios/Runner/Info.plist
@@ -41,8 +41,6 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
- <key>UIViewControllerBasedStatusBarAppearance</key>
- <false/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
diff --git a/dev/integration_tests/channels/pubspec.yaml b/dev/integration_tests/channels/pubspec.yaml
index f79f3f5..0a8e882 100644
--- a/dev/integration_tests/channels/pubspec.yaml
+++ b/dev/integration_tests/channels/pubspec.yaml
@@ -10,10 +10,10 @@
characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
collection: 1.17.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.9.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
integration_test:
@@ -31,16 +31,16 @@
matcher: 0.12.16 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path: 1.8.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
sync_http: 0.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- vm_service: 11.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ vm_service: 11.7.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
flutter:
uses-material-design: true
-# PUBSPEC CHECKSUM: bb0e
+# PUBSPEC CHECKSUM: 4738
diff --git a/dev/integration_tests/deferred_components_test/pubspec.yaml b/dev/integration_tests/deferred_components_test/pubspec.yaml
index 15cd835..0aa2933 100644
--- a/dev/integration_tests/deferred_components_test/pubspec.yaml
+++ b/dev/integration_tests/deferred_components_test/pubspec.yaml
@@ -16,40 +16,42 @@
characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
collection: 1.17.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
file: 6.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
matcher: 0.12.16 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.9.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path: 1.8.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
sync_http: 0.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- vm_service: 11.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ vm_service: 11.7.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
flutter_test:
sdk: flutter
- test: 1.24.3
+ test: 1.24.4
- _fe_analyzer_shared: 61.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- analyzer: 5.13.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ _fe_analyzer_shared: 62.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ analyzer: 6.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
args: 2.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
clock: 1.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
convert: 3.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
coverage: 1.6.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
crypto: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ dart_internal: 0.2.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
fake_async: 1.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
frontend_server_client: 3.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
glob: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http_multi_server: 3.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http_parser: 4.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
io: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
logging: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
mime: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
node_preamble: 2.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -62,7 +64,7 @@
shelf_web_socket: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_map_stack_trace: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_maps: 0.10.12 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_core: 0.5.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_core: 0.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -79,4 +81,4 @@
assets:
- customassets/flutter_logo.png
-# PUBSPEC CHECKSUM: db36
+# PUBSPEC CHECKSUM: be20
diff --git a/dev/integration_tests/external_ui/android/build.gradle b/dev/integration_tests/external_ui/android/build.gradle
index 57ace36..a2a8866 100644
--- a/dev/integration_tests/external_ui/android/build.gradle
+++ b/dev/integration_tests/external_ui/android/build.gradle
@@ -7,14 +7,14 @@
// See dev/tools/bin/generate_gradle_lockfiles.dart.
buildscript {
- ext.kotlin_version = '1.5.31'
+ ext.kotlin_version = '1.7.10'
repositories {
google()
mavenCentral()
}
dependencies {
- classpath 'com.android.tools.build:gradle:4.1.3'
+ classpath 'com.android.tools.build:gradle:7.3.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
diff --git a/dev/integration_tests/external_ui/android/buildscript-gradle.lockfile b/dev/integration_tests/external_ui/android/buildscript-gradle.lockfile
index 2577f0a..eb60580 100644
--- a/dev/integration_tests/external_ui/android/buildscript-gradle.lockfile
+++ b/dev/integration_tests/external_ui/android/buildscript-gradle.lockfile
@@ -1,120 +1,152 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
-androidx.databinding:databinding-common:4.1.3=classpath
-androidx.databinding:databinding-compiler-common:4.1.3=classpath
-com.android.databinding:baseLibrary:4.1.3=classpath
-com.android.tools.analytics-library:crash:27.1.3=classpath
-com.android.tools.analytics-library:protos:27.1.3=classpath
-com.android.tools.analytics-library:shared:27.1.3=classpath
-com.android.tools.analytics-library:tracker:27.1.3=classpath
-com.android.tools.build.jetifier:jetifier-core:1.0.0-beta09=classpath
-com.android.tools.build.jetifier:jetifier-processor:1.0.0-beta09=classpath
-com.android.tools.build:aapt2-proto:4.1.3-6503028=classpath
-com.android.tools.build:aaptcompiler:4.1.3=classpath
-com.android.tools.build:apksig:4.1.3=classpath
-com.android.tools.build:apkzlib:4.1.3=classpath
-com.android.tools.build:builder-model:4.1.3=classpath
-com.android.tools.build:builder-test-api:4.1.3=classpath
-com.android.tools.build:builder:4.1.3=classpath
-com.android.tools.build:bundletool:0.14.0=classpath
-com.android.tools.build:gradle-api:4.1.3=classpath
-com.android.tools.build:gradle:4.1.3=classpath
-com.android.tools.build:manifest-merger:27.1.3=classpath
+androidx.databinding:databinding-common:7.3.0=classpath
+androidx.databinding:databinding-compiler-common:7.3.0=classpath
+com.android.databinding:baseLibrary:7.3.0=classpath
+com.android.tools.analytics-library:crash:30.3.0=classpath
+com.android.tools.analytics-library:protos:30.3.0=classpath
+com.android.tools.analytics-library:shared:30.3.0=classpath
+com.android.tools.analytics-library:tracker:30.3.0=classpath
+com.android.tools.build.jetifier:jetifier-core:1.0.0-beta10=classpath
+com.android.tools.build.jetifier:jetifier-processor:1.0.0-beta10=classpath
+com.android.tools.build:aapt2-proto:7.3.0-8691043=classpath
+com.android.tools.build:aaptcompiler:7.3.0=classpath
+com.android.tools.build:apksig:7.3.0=classpath
+com.android.tools.build:apkzlib:7.3.0=classpath
+com.android.tools.build:builder-model:7.3.0=classpath
+com.android.tools.build:builder-test-api:7.3.0=classpath
+com.android.tools.build:builder:7.3.0=classpath
+com.android.tools.build:bundletool:1.9.0=classpath
+com.android.tools.build:gradle-api:7.3.0=classpath
+com.android.tools.build:gradle:7.3.0=classpath
+com.android.tools.build:manifest-merger:30.3.0=classpath
com.android.tools.build:transform-api:2.0.0-deprecated-use-gradle-api=classpath
-com.android.tools.ddms:ddmlib:27.1.3=classpath
-com.android.tools.layoutlib:layoutlib-api:27.1.3=classpath
-com.android.tools.lint:lint-gradle-api:27.1.3=classpath
-com.android.tools.lint:lint-model:27.1.3=classpath
-com.android.tools:annotations:27.1.3=classpath
-com.android.tools:common:27.1.3=classpath
-com.android.tools:dvlib:27.1.3=classpath
-com.android.tools:repository:27.1.3=classpath
-com.android.tools:sdk-common:27.1.3=classpath
-com.android.tools:sdklib:27.1.3=classpath
-com.android:signflinger:4.1.3=classpath
-com.android:zipflinger:4.1.3=classpath
+com.android.tools.ddms:ddmlib:30.3.0=classpath
+com.android.tools.layoutlib:layoutlib-api:30.3.0=classpath
+com.android.tools.lint:lint-model:30.3.0=classpath
+com.android.tools.lint:lint-typedef-remover:30.3.0=classpath
+com.android.tools.utp:android-device-provider-ddmlib-proto:30.3.0=classpath
+com.android.tools.utp:android-device-provider-gradle-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-host-additional-test-output-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-host-coverage-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-host-retention-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-result-listener-gradle-proto:30.3.0=classpath
+com.android.tools:annotations:30.3.0=classpath
+com.android.tools:common:30.3.0=classpath
+com.android.tools:dvlib:30.3.0=classpath
+com.android.tools:repository:30.3.0=classpath
+com.android.tools:sdk-common:30.3.0=classpath
+com.android.tools:sdklib:30.3.0=classpath
+com.android:signflinger:7.3.0=classpath
+com.android:zipflinger:7.3.0=classpath
com.github.gundy:semver4j:0.16.4=classpath
+com.google.android:annotations:4.1.1.4=classpath
+com.google.api.grpc:proto-google-common-protos:2.0.1=classpath
com.google.auto.value:auto-value-annotations:1.6.2=classpath
com.google.code.findbugs:jsr305:3.0.2=classpath
-com.google.code.gson:gson:2.8.6=classpath
+com.google.code.gson:gson:2.8.9=classpath
com.google.crypto.tink:tink:1.3.0-rc2=classpath
-com.google.errorprone:error_prone_annotations:2.3.4=classpath
+com.google.dagger:dagger:2.28.3=classpath
+com.google.errorprone:error_prone_annotations:2.4.0=classpath
com.google.flatbuffers:flatbuffers-java:1.12.0=classpath
com.google.guava:failureaccess:1.0.1=classpath
-com.google.guava:guava:29.0-jre=classpath
+com.google.guava:guava:30.1-jre=classpath
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=classpath
com.google.j2objc:j2objc-annotations:1.3=classpath
com.google.jimfs:jimfs:1.1=classpath
-com.google.protobuf:protobuf-java-util:3.10.0=classpath
-com.google.protobuf:protobuf-java:3.10.0=classpath
-com.google.test.platform:core-proto:0.0.2-dev=classpath
+com.google.protobuf:protobuf-java-util:3.17.2=classpath
+com.google.protobuf:protobuf-java:3.17.2=classpath
+com.google.testing.platform:core-proto:0.0.8-alpha07=classpath
com.googlecode.json-simple:json-simple:1.1=classpath
com.googlecode.juniversalchardet:juniversalchardet:1.0.3=classpath
com.squareup:javapoet:1.10.0=classpath
com.squareup:javawriter:2.5.0=classpath
com.sun.activation:javax.activation:1.2.0=classpath
-com.sun.istack:istack-commons-runtime:3.0.7=classpath
-com.sun.xml.fastinfoset:FastInfoset:1.2.15=classpath
-commons-codec:commons-codec:1.10=classpath
+com.sun.istack:istack-commons-runtime:3.0.8=classpath
+com.sun.xml.fastinfoset:FastInfoset:1.2.16=classpath
+commons-codec:commons-codec:1.11=classpath
commons-io:commons-io:2.4=classpath
commons-logging:commons-logging:1.2=classpath
de.undercouch:gradle-download-task:4.1.1=classpath
-it.unimi.dsi:fastutil:7.2.0=classpath
-javax.activation:javax.activation-api:1.2.0=classpath
+io.grpc:grpc-api:1.39.0=classpath
+io.grpc:grpc-context:1.39.0=classpath
+io.grpc:grpc-core:1.39.0=classpath
+io.grpc:grpc-netty:1.39.0=classpath
+io.grpc:grpc-protobuf-lite:1.39.0=classpath
+io.grpc:grpc-protobuf:1.39.0=classpath
+io.grpc:grpc-stub:1.39.0=classpath
+io.netty:netty-buffer:4.1.52.Final=classpath
+io.netty:netty-codec-http2:4.1.52.Final=classpath
+io.netty:netty-codec-http:4.1.52.Final=classpath
+io.netty:netty-codec-socks:4.1.52.Final=classpath
+io.netty:netty-codec:4.1.52.Final=classpath
+io.netty:netty-common:4.1.52.Final=classpath
+io.netty:netty-handler-proxy:4.1.52.Final=classpath
+io.netty:netty-handler:4.1.52.Final=classpath
+io.netty:netty-resolver:4.1.52.Final=classpath
+io.netty:netty-transport:4.1.52.Final=classpath
+io.perfmark:perfmark-api:0.23.0=classpath
+it.unimi.dsi:fastutil:8.4.0=classpath
+jakarta.activation:jakarta.activation-api:1.2.1=classpath
+jakarta.xml.bind:jakarta.xml.bind-api:2.3.2=classpath
+javax.annotation:javax.annotation-api:1.3.2=classpath
javax.inject:javax.inject:1=classpath
-javax.xml.bind:jaxb-api:2.3.1=classpath
+net.java.dev.jna:jna-platform:5.6.0=classpath
+net.java.dev.jna:jna:5.6.0=classpath
net.sf.jopt-simple:jopt-simple:4.9=classpath
net.sf.kxml:kxml2:2.3.0=classpath
-net.sf.proguard:proguard-base:6.0.3=classpath
-net.sf.proguard:proguard-gradle:6.0.3=classpath
-org.antlr:antlr4:4.5.3=classpath
-org.apache.commons:commons-compress:1.12=classpath
-org.apache.httpcomponents:httpclient:4.5.6=classpath
-org.apache.httpcomponents:httpcore:4.4.10=classpath
+org.apache.commons:commons-compress:1.20=classpath
+org.apache.httpcomponents:httpclient:4.5.13=classpath
+org.apache.httpcomponents:httpcore:4.4.13=classpath
org.apache.httpcomponents:httpmime:4.5.6=classpath
-org.bouncycastle:bcpkix-jdk15on:1.56=classpath
-org.bouncycastle:bcprov-jdk15on:1.56=classpath
-org.checkerframework:checker-qual:2.11.1=classpath
-org.glassfish.jaxb:jaxb-runtime:2.3.1=classpath
-org.glassfish.jaxb:txw2:2.3.1=classpath
+org.bitbucket.b_c:jose4j:0.7.0=classpath
+org.bouncycastle:bcpkix-jdk15on:1.67=classpath
+org.bouncycastle:bcprov-jdk15on:1.67=classpath
+org.checkerframework:checker-qual:3.5.0=classpath
+org.codehaus.mojo:animal-sniffer-annotations:1.19=classpath
+org.glassfish.jaxb:jaxb-runtime:2.3.2=classpath
+org.glassfish.jaxb:txw2:2.3.2=classpath
org.jdom:jdom2:2.0.6=classpath
-org.jetbrains.intellij.deps:trove4j:1.0.20181211=classpath
-org.jetbrains.kotlin:kotlin-android-extensions:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-annotation-processing-gradle:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-build-common:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-compiler-embeddable:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-compiler-runner:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-daemon-client:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-daemon-embeddable:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-native-utils:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-project-model:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-reflect:1.3.72=classpath
-org.jetbrains.kotlin:kotlin-scripting-common:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-scripting-jvm:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-stdlib-common:1.3.72=classpath
-org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.72=classpath
-org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.72=classpath
-org.jetbrains.kotlin:kotlin-stdlib:1.3.72=classpath
-org.jetbrains.kotlin:kotlin-tooling-metadata:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-util-io:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-util-klib:1.5.31=classpath
+org.jetbrains.intellij.deps:trove4j:1.0.20200330=classpath
+org.jetbrains.kotlin:kotlin-android-extensions:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-annotation-processing-gradle:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-build-common:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-compiler-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-compiler-runner:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-daemon-client:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-daemon-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin-idea:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-native-utils:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-project-model:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-reflect:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-scripting-common:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-scripting-jvm:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-stdlib-common:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-stdlib:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-tooling-core:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-tooling-metadata:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-util-io:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-util-klib:1.7.10=classpath
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.0=classpath
-org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0=classpath
-org.jetbrains.trove4j:trove4j:20160824=classpath
org.jetbrains:annotations:13.0=classpath
org.json:json:20180813=classpath
-org.jvnet.staxex:stax-ex:1.8=classpath
-org.ow2.asm:asm-analysis:7.0=classpath
-org.ow2.asm:asm-commons:7.0=classpath
-org.ow2.asm:asm-tree:7.0=classpath
-org.ow2.asm:asm-util:7.0=classpath
-org.ow2.asm:asm:7.0=classpath
-org.tensorflow:tensorflow-lite-metadata:0.1.0-rc1=classpath
+org.jvnet.staxex:stax-ex:1.8.1=classpath
+org.ow2.asm:asm-analysis:9.1=classpath
+org.ow2.asm:asm-commons:9.1=classpath
+org.ow2.asm:asm-tree:9.1=classpath
+org.ow2.asm:asm-util:9.1=classpath
+org.ow2.asm:asm:9.1=classpath
+org.slf4j:slf4j-api:1.7.30=classpath
+org.tensorflow:tensorflow-lite-metadata:0.1.0-rc2=classpath
+xerces:xercesImpl:2.12.0=classpath
+xml-apis:xml-apis:1.4.01=classpath
empty=
diff --git a/dev/integration_tests/external_ui/android/project-app.lockfile b/dev/integration_tests/external_ui/android/project-app.lockfile
index 7e81cc2..e160a81 100644
--- a/dev/integration_tests/external_ui/android/project-app.lockfile
+++ b/dev/integration_tests/external_ui/android/project-app.lockfile
@@ -87,6 +87,10 @@
org.codehaus.mojo:animal-sniffer-annotations:1.18=lintClassPath
org.glassfish.jaxb:jaxb-runtime:2.3.1=lintClassPath
org.glassfish.jaxb:txw2:2.3.1=lintClassPath
+org.jacoco:org.jacoco.agent:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.ant:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.core:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.report:0.8.7=androidJacocoAnt
org.jetbrains.kotlin:kotlin-reflect:1.3.72=lintClassPath
org.jetbrains.kotlin:kotlin-stdlib-common:1.3.72=lintClassPath
org.jetbrains.kotlin:kotlin-stdlib-common:1.5.31=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
@@ -103,8 +107,12 @@
org.jetbrains:annotations:13.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,lintClassPath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.jvnet.staxex:stax-ex:1.8=lintClassPath
org.ow2.asm:asm-analysis:7.0=lintClassPath
+org.ow2.asm:asm-analysis:9.1=androidJacocoAnt
org.ow2.asm:asm-commons:7.0=lintClassPath
+org.ow2.asm:asm-commons:9.1=androidJacocoAnt
org.ow2.asm:asm-tree:7.0=lintClassPath
+org.ow2.asm:asm-tree:9.1=androidJacocoAnt
org.ow2.asm:asm-util:7.0=lintClassPath
org.ow2.asm:asm:7.0=lintClassPath
-empty=androidApis,androidTestUtil,compile,coreLibraryDesugaring,debugAndroidTestAnnotationProcessorClasspath,debugAndroidTestRuntimeClasspath,debugAnnotationProcessorClasspath,debugReverseMetadataValues,debugUnitTestAnnotationProcessorClasspath,debugWearBundling,lintChecks,lintPublish,profileAnnotationProcessorClasspath,profileReverseMetadataValues,profileUnitTestAnnotationProcessorClasspath,profileWearBundling,releaseAnnotationProcessorClasspath,releaseReverseMetadataValues,releaseUnitTestAnnotationProcessorClasspath,releaseWearBundling,testCompile
+org.ow2.asm:asm:9.1=androidJacocoAnt
+empty=androidApis,androidJdkImage,androidTestUtil,compile,coreLibraryDesugaring,debugAndroidTestAnnotationProcessorClasspath,debugAndroidTestRuntimeClasspath,debugAnnotationProcessorClasspath,debugReverseMetadataValues,debugUnitTestAnnotationProcessorClasspath,debugWearBundling,lintChecks,lintPublish,profileAnnotationProcessorClasspath,profileReverseMetadataValues,profileUnitTestAnnotationProcessorClasspath,profileWearBundling,releaseAnnotationProcessorClasspath,releaseReverseMetadataValues,releaseUnitTestAnnotationProcessorClasspath,releaseWearBundling,testCompile
diff --git a/dev/integration_tests/external_ui/android/settings.gradle b/dev/integration_tests/external_ui/android/settings.gradle
index 03ae72d..a020595 100644
--- a/dev/integration_tests/external_ui/android/settings.gradle
+++ b/dev/integration_tests/external_ui/android/settings.gradle
@@ -8,8 +8,6 @@
include ':app'
-enableFeaturePreview('ONE_LOCKFILE_PER_PROJECT')
-
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()
diff --git a/dev/integration_tests/external_ui/ios/Runner/Info.plist b/dev/integration_tests/external_ui/ios/Runner/Info.plist
index 2af2a77..60d8199 100644
--- a/dev/integration_tests/external_ui/ios/Runner/Info.plist
+++ b/dev/integration_tests/external_ui/ios/Runner/Info.plist
@@ -39,8 +39,6 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
- <key>UIViewControllerBasedStatusBarAppearance</key>
- <false/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
diff --git a/dev/integration_tests/external_ui/pubspec.yaml b/dev/integration_tests/external_ui/pubspec.yaml
index 333cff0..d0e1921 100644
--- a/dev/integration_tests/external_ui/pubspec.yaml
+++ b/dev/integration_tests/external_ui/pubspec.yaml
@@ -9,10 +9,10 @@
sdk: flutter
flutter_driver:
sdk: flutter
- test: 1.24.3
+ test: 1.24.4
- _fe_analyzer_shared: 61.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- analyzer: 5.13.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ _fe_analyzer_shared: 62.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ analyzer: 6.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
args: 2.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
async: 2.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -21,6 +21,7 @@
convert: 3.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
coverage: 1.6.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
crypto: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ dart_internal: 0.2.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
file: 6.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
frontend_server_client: 3.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
glob: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -45,17 +46,18 @@
source_map_stack_trace: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_maps: 0.10.12 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
sync_http: 0.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_core: 0.5.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_core: 0.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- vm_service: 11.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ vm_service: 11.7.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -64,4 +66,4 @@
flutter:
uses-material-design: true
-# PUBSPEC CHECKSUM: a079
+# PUBSPEC CHECKSUM: c363
diff --git a/dev/integration_tests/flavors/android/build.gradle b/dev/integration_tests/flavors/android/build.gradle
index 2de2062..a2a8866 100644
--- a/dev/integration_tests/flavors/android/build.gradle
+++ b/dev/integration_tests/flavors/android/build.gradle
@@ -7,14 +7,14 @@
// See dev/tools/bin/generate_gradle_lockfiles.dart.
buildscript {
- ext.kotlin_version = '1.5.31'
+ ext.kotlin_version = '1.7.10'
repositories {
google()
mavenCentral()
}
dependencies {
- classpath 'com.android.tools.build:gradle:7.2.0'
+ classpath 'com.android.tools.build:gradle:7.3.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
diff --git a/dev/integration_tests/flavors/android/buildscript-gradle.lockfile b/dev/integration_tests/flavors/android/buildscript-gradle.lockfile
index efe1327..eb60580 100644
--- a/dev/integration_tests/flavors/android/buildscript-gradle.lockfile
+++ b/dev/integration_tests/flavors/android/buildscript-gradle.lockfile
@@ -1,69 +1,62 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
-androidx.databinding:databinding-common:7.2.0=classpath
-androidx.databinding:databinding-compiler-common:7.2.0=classpath
-com.android.databinding:baseLibrary:7.2.0=classpath
-com.android.tools.analytics-library:crash:30.2.0=classpath
-com.android.tools.analytics-library:protos:30.2.0=classpath
-com.android.tools.analytics-library:shared:30.2.0=classpath
-com.android.tools.analytics-library:tracker:30.2.0=classpath
-com.android.tools.build.jetifier:jetifier-core:1.0.0-beta09=classpath
-com.android.tools.build.jetifier:jetifier-processor:1.0.0-beta09=classpath
-com.android.tools.build:aapt2-proto:7.2.0-7984345=classpath
-com.android.tools.build:aaptcompiler:7.2.0=classpath
-com.android.tools.build:apksig:7.2.0=classpath
-com.android.tools.build:apkzlib:7.2.0=classpath
-com.android.tools.build:builder-model:7.2.0=classpath
-com.android.tools.build:builder-test-api:7.2.0=classpath
-com.android.tools.build:builder:7.2.0=classpath
-com.android.tools.build:bundletool:1.8.2=classpath
-com.android.tools.build:gradle-api:7.2.0=classpath
-com.android.tools.build:gradle:7.2.0=classpath
-com.android.tools.build:manifest-merger:30.2.0=classpath
+androidx.databinding:databinding-common:7.3.0=classpath
+androidx.databinding:databinding-compiler-common:7.3.0=classpath
+com.android.databinding:baseLibrary:7.3.0=classpath
+com.android.tools.analytics-library:crash:30.3.0=classpath
+com.android.tools.analytics-library:protos:30.3.0=classpath
+com.android.tools.analytics-library:shared:30.3.0=classpath
+com.android.tools.analytics-library:tracker:30.3.0=classpath
+com.android.tools.build.jetifier:jetifier-core:1.0.0-beta10=classpath
+com.android.tools.build.jetifier:jetifier-processor:1.0.0-beta10=classpath
+com.android.tools.build:aapt2-proto:7.3.0-8691043=classpath
+com.android.tools.build:aaptcompiler:7.3.0=classpath
+com.android.tools.build:apksig:7.3.0=classpath
+com.android.tools.build:apkzlib:7.3.0=classpath
+com.android.tools.build:builder-model:7.3.0=classpath
+com.android.tools.build:builder-test-api:7.3.0=classpath
+com.android.tools.build:builder:7.3.0=classpath
+com.android.tools.build:bundletool:1.9.0=classpath
+com.android.tools.build:gradle-api:7.3.0=classpath
+com.android.tools.build:gradle:7.3.0=classpath
+com.android.tools.build:manifest-merger:30.3.0=classpath
com.android.tools.build:transform-api:2.0.0-deprecated-use-gradle-api=classpath
-com.android.tools.ddms:ddmlib:30.2.0=classpath
-com.android.tools.layoutlib:layoutlib-api:30.2.0=classpath
-com.android.tools.lint:lint-model:30.2.0=classpath
-com.android.tools.lint:lint-typedef-remover:30.2.0=classpath
-com.android.tools.utp:android-device-provider-ddmlib-proto:30.2.0=classpath
-com.android.tools.utp:android-device-provider-gradle-proto:30.2.0=classpath
-com.android.tools.utp:android-test-plugin-host-additional-test-output-proto:30.2.0=classpath
-com.android.tools.utp:android-test-plugin-host-coverage-proto:30.2.0=classpath
-com.android.tools.utp:android-test-plugin-host-retention-proto:30.2.0=classpath
-com.android.tools.utp:android-test-plugin-result-listener-gradle-proto:30.2.0=classpath
-com.android.tools:annotations:30.2.0=classpath
-com.android.tools:common:30.2.0=classpath
-com.android.tools:dvlib:30.2.0=classpath
-com.android.tools:repository:30.2.0=classpath
-com.android.tools:sdk-common:30.2.0=classpath
-com.android.tools:sdklib:30.2.0=classpath
-com.android:signflinger:7.2.0=classpath
-com.android:zipflinger:7.2.0=classpath
-com.fasterxml.jackson.core:jackson-annotations:2.11.1=classpath
-com.fasterxml.jackson.core:jackson-core:2.11.1=classpath
-com.fasterxml.jackson.core:jackson-databind:2.11.1=classpath
-com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.11.1=classpath
-com.fasterxml.jackson.module:jackson-module-jaxb-annotations:2.11.1=classpath
-com.fasterxml.jackson.module:jackson-module-kotlin:2.11.1=classpath
-com.fasterxml.woodstox:woodstox-core:6.2.1=classpath
+com.android.tools.ddms:ddmlib:30.3.0=classpath
+com.android.tools.layoutlib:layoutlib-api:30.3.0=classpath
+com.android.tools.lint:lint-model:30.3.0=classpath
+com.android.tools.lint:lint-typedef-remover:30.3.0=classpath
+com.android.tools.utp:android-device-provider-ddmlib-proto:30.3.0=classpath
+com.android.tools.utp:android-device-provider-gradle-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-host-additional-test-output-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-host-coverage-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-host-retention-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-result-listener-gradle-proto:30.3.0=classpath
+com.android.tools:annotations:30.3.0=classpath
+com.android.tools:common:30.3.0=classpath
+com.android.tools:dvlib:30.3.0=classpath
+com.android.tools:repository:30.3.0=classpath
+com.android.tools:sdk-common:30.3.0=classpath
+com.android.tools:sdklib:30.3.0=classpath
+com.android:signflinger:7.3.0=classpath
+com.android:zipflinger:7.3.0=classpath
com.github.gundy:semver4j:0.16.4=classpath
com.google.android:annotations:4.1.1.4=classpath
-com.google.api.grpc:proto-google-common-protos:1.12.0=classpath
+com.google.api.grpc:proto-google-common-protos:2.0.1=classpath
com.google.auto.value:auto-value-annotations:1.6.2=classpath
com.google.code.findbugs:jsr305:3.0.2=classpath
-com.google.code.gson:gson:2.8.6=classpath
+com.google.code.gson:gson:2.8.9=classpath
com.google.crypto.tink:tink:1.3.0-rc2=classpath
com.google.dagger:dagger:2.28.3=classpath
-com.google.errorprone:error_prone_annotations:2.3.4=classpath
+com.google.errorprone:error_prone_annotations:2.4.0=classpath
com.google.flatbuffers:flatbuffers-java:1.12.0=classpath
com.google.guava:failureaccess:1.0.1=classpath
com.google.guava:guava:30.1-jre=classpath
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=classpath
com.google.j2objc:j2objc-annotations:1.3=classpath
com.google.jimfs:jimfs:1.1=classpath
-com.google.protobuf:protobuf-java-util:3.10.0=classpath
-com.google.protobuf:protobuf-java:3.10.0=classpath
+com.google.protobuf:protobuf-java-util:3.17.2=classpath
+com.google.protobuf:protobuf-java:3.17.2=classpath
com.google.testing.platform:core-proto:0.0.8-alpha07=classpath
com.googlecode.json-simple:json-simple:1.1=classpath
com.googlecode.juniversalchardet:juniversalchardet:1.0.3=classpath
@@ -76,80 +69,76 @@
commons-io:commons-io:2.4=classpath
commons-logging:commons-logging:1.2=classpath
de.undercouch:gradle-download-task:4.1.1=classpath
-io.grpc:grpc-api:1.21.1=classpath
-io.grpc:grpc-context:1.21.1=classpath
-io.grpc:grpc-core:1.21.1=classpath
-io.grpc:grpc-netty:1.21.1=classpath
-io.grpc:grpc-protobuf-lite:1.21.1=classpath
-io.grpc:grpc-protobuf:1.21.1=classpath
-io.grpc:grpc-stub:1.21.1=classpath
-io.netty:netty-buffer:4.1.34.Final=classpath
-io.netty:netty-codec-http2:4.1.34.Final=classpath
-io.netty:netty-codec-http:4.1.34.Final=classpath
-io.netty:netty-codec-socks:4.1.34.Final=classpath
-io.netty:netty-codec:4.1.34.Final=classpath
-io.netty:netty-common:4.1.34.Final=classpath
-io.netty:netty-handler-proxy:4.1.34.Final=classpath
-io.netty:netty-handler:4.1.34.Final=classpath
-io.netty:netty-resolver:4.1.34.Final=classpath
-io.netty:netty-transport:4.1.34.Final=classpath
-io.opencensus:opencensus-api:0.21.0=classpath
-io.opencensus:opencensus-contrib-grpc-metrics:0.21.0=classpath
+io.grpc:grpc-api:1.39.0=classpath
+io.grpc:grpc-context:1.39.0=classpath
+io.grpc:grpc-core:1.39.0=classpath
+io.grpc:grpc-netty:1.39.0=classpath
+io.grpc:grpc-protobuf-lite:1.39.0=classpath
+io.grpc:grpc-protobuf:1.39.0=classpath
+io.grpc:grpc-stub:1.39.0=classpath
+io.netty:netty-buffer:4.1.52.Final=classpath
+io.netty:netty-codec-http2:4.1.52.Final=classpath
+io.netty:netty-codec-http:4.1.52.Final=classpath
+io.netty:netty-codec-socks:4.1.52.Final=classpath
+io.netty:netty-codec:4.1.52.Final=classpath
+io.netty:netty-common:4.1.52.Final=classpath
+io.netty:netty-handler-proxy:4.1.52.Final=classpath
+io.netty:netty-handler:4.1.52.Final=classpath
+io.netty:netty-resolver:4.1.52.Final=classpath
+io.netty:netty-transport:4.1.52.Final=classpath
+io.perfmark:perfmark-api:0.23.0=classpath
it.unimi.dsi:fastutil:8.4.0=classpath
jakarta.activation:jakarta.activation-api:1.2.1=classpath
jakarta.xml.bind:jakarta.xml.bind-api:2.3.2=classpath
+javax.annotation:javax.annotation-api:1.3.2=classpath
javax.inject:javax.inject:1=classpath
net.java.dev.jna:jna-platform:5.6.0=classpath
net.java.dev.jna:jna:5.6.0=classpath
net.sf.jopt-simple:jopt-simple:4.9=classpath
net.sf.kxml:kxml2:2.3.0=classpath
org.apache.commons:commons-compress:1.20=classpath
-org.apache.httpcomponents:httpclient:4.5.9=classpath
-org.apache.httpcomponents:httpcore:4.4.11=classpath
+org.apache.httpcomponents:httpclient:4.5.13=classpath
+org.apache.httpcomponents:httpcore:4.4.13=classpath
org.apache.httpcomponents:httpmime:4.5.6=classpath
org.bitbucket.b_c:jose4j:0.7.0=classpath
-org.bouncycastle:bcpkix-jdk15on:1.56=classpath
-org.bouncycastle:bcprov-jdk15on:1.56=classpath
+org.bouncycastle:bcpkix-jdk15on:1.67=classpath
+org.bouncycastle:bcprov-jdk15on:1.67=classpath
org.checkerframework:checker-qual:3.5.0=classpath
-org.codehaus.mojo:animal-sniffer-annotations:1.17=classpath
-org.codehaus.woodstox:stax2-api:4.2.1=classpath
+org.codehaus.mojo:animal-sniffer-annotations:1.19=classpath
org.glassfish.jaxb:jaxb-runtime:2.3.2=classpath
org.glassfish.jaxb:txw2:2.3.2=classpath
org.jdom:jdom2:2.0.6=classpath
-org.jetbrains.dokka:dokka-core:1.4.32=classpath
-org.jetbrains.intellij.deps:trove4j:1.0.20181211=classpath
-org.jetbrains.kotlin:kotlin-android-extensions:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-annotation-processing-gradle:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-build-common:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-compiler-embeddable:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-compiler-runner:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-daemon-client:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-daemon-embeddable:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-native-utils:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-project-model:1.5.31=classpath
+org.jetbrains.intellij.deps:trove4j:1.0.20200330=classpath
+org.jetbrains.kotlin:kotlin-android-extensions:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-annotation-processing-gradle:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-build-common:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-compiler-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-compiler-runner:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-daemon-client:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-daemon-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin-idea:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-native-utils:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-project-model:1.7.10=classpath
org.jetbrains.kotlin:kotlin-reflect:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-scripting-common:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-scripting-jvm:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-scripting-common:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-scripting-jvm:1.7.10=classpath
org.jetbrains.kotlin:kotlin-stdlib-common:1.5.31=classpath
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.5.31=classpath
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.31=classpath
org.jetbrains.kotlin:kotlin-stdlib:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-tooling-metadata:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-util-io:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-util-klib:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-tooling-core:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-tooling-metadata:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-util-io:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-util-klib:1.7.10=classpath
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.0=classpath
-org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0=classpath
org.jetbrains:annotations:13.0=classpath
-org.jetbrains:markdown-jvm:0.2.1=classpath
-org.jetbrains:markdown:0.2.1=classpath
org.json:json:20180813=classpath
-org.jsoup:jsoup:1.13.1=classpath
org.jvnet.staxex:stax-ex:1.8.1=classpath
org.ow2.asm:asm-analysis:9.1=classpath
org.ow2.asm:asm-commons:9.1=classpath
diff --git a/dev/integration_tests/flavors/android/gradle/wrapper/gradle-wrapper.properties b/dev/integration_tests/flavors/android/gradle/wrapper/gradle-wrapper.properties
index f338a88..cb24abd 100644
--- a/dev/integration_tests/flavors/android/gradle/wrapper/gradle-wrapper.properties
+++ b/dev/integration_tests/flavors/android/gradle/wrapper/gradle-wrapper.properties
@@ -2,4 +2,4 @@
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip
diff --git a/dev/integration_tests/flavors/android/settings.gradle b/dev/integration_tests/flavors/android/settings.gradle
index 03ae72d..a020595 100644
--- a/dev/integration_tests/flavors/android/settings.gradle
+++ b/dev/integration_tests/flavors/android/settings.gradle
@@ -8,8 +8,6 @@
include ':app'
-enableFeaturePreview('ONE_LOCKFILE_PER_PROJECT')
-
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()
diff --git a/dev/integration_tests/flavors/ios/Runner/Info-Free.plist b/dev/integration_tests/flavors/ios/Runner/Info-Free.plist
index ce8c723..b6853d5 100644
--- a/dev/integration_tests/flavors/ios/Runner/Info-Free.plist
+++ b/dev/integration_tests/flavors/ios/Runner/Info-Free.plist
@@ -41,8 +41,6 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
- <key>UIViewControllerBasedStatusBarAppearance</key>
- <false/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
</dict>
diff --git a/dev/integration_tests/flavors/ios/Runner/Info-Paid.plist b/dev/integration_tests/flavors/ios/Runner/Info-Paid.plist
index ce8c723..b6853d5 100644
--- a/dev/integration_tests/flavors/ios/Runner/Info-Paid.plist
+++ b/dev/integration_tests/flavors/ios/Runner/Info-Paid.plist
@@ -41,8 +41,6 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
- <key>UIViewControllerBasedStatusBarAppearance</key>
- <false/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
</dict>
diff --git a/dev/integration_tests/flavors/pubspec.yaml b/dev/integration_tests/flavors/pubspec.yaml
index 07fddb1..4a1bf4d 100644
--- a/dev/integration_tests/flavors/pubspec.yaml
+++ b/dev/integration_tests/flavors/pubspec.yaml
@@ -11,10 +11,10 @@
sdk: flutter
integration_test:
sdk: flutter
- test: 1.24.3
+ test: 1.24.4
- _fe_analyzer_shared: 61.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- analyzer: 5.13.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ _fe_analyzer_shared: 62.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ analyzer: 6.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
args: 2.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
async: 2.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -23,6 +23,7 @@
convert: 3.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
coverage: 1.6.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
crypto: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ dart_internal: 0.2.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
file: 6.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
frontend_server_client: 3.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
glob: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -47,17 +48,18 @@
source_map_stack_trace: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_maps: 0.10.12 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
sync_http: 0.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_core: 0.5.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_core: 0.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- vm_service: 11.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ vm_service: 11.7.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -73,4 +75,4 @@
flutter:
uses-material-design: true
-# PUBSPEC CHECKSUM: db36
+# PUBSPEC CHECKSUM: be20
diff --git a/dev/integration_tests/flutter_gallery/android/build.gradle b/dev/integration_tests/flutter_gallery/android/build.gradle
index 2de2062..a2a8866 100644
--- a/dev/integration_tests/flutter_gallery/android/build.gradle
+++ b/dev/integration_tests/flutter_gallery/android/build.gradle
@@ -7,14 +7,14 @@
// See dev/tools/bin/generate_gradle_lockfiles.dart.
buildscript {
- ext.kotlin_version = '1.5.31'
+ ext.kotlin_version = '1.7.10'
repositories {
google()
mavenCentral()
}
dependencies {
- classpath 'com.android.tools.build:gradle:7.2.0'
+ classpath 'com.android.tools.build:gradle:7.3.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
diff --git a/dev/integration_tests/flutter_gallery/android/buildscript-gradle.lockfile b/dev/integration_tests/flutter_gallery/android/buildscript-gradle.lockfile
index efe1327..eb60580 100644
--- a/dev/integration_tests/flutter_gallery/android/buildscript-gradle.lockfile
+++ b/dev/integration_tests/flutter_gallery/android/buildscript-gradle.lockfile
@@ -1,69 +1,62 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
-androidx.databinding:databinding-common:7.2.0=classpath
-androidx.databinding:databinding-compiler-common:7.2.0=classpath
-com.android.databinding:baseLibrary:7.2.0=classpath
-com.android.tools.analytics-library:crash:30.2.0=classpath
-com.android.tools.analytics-library:protos:30.2.0=classpath
-com.android.tools.analytics-library:shared:30.2.0=classpath
-com.android.tools.analytics-library:tracker:30.2.0=classpath
-com.android.tools.build.jetifier:jetifier-core:1.0.0-beta09=classpath
-com.android.tools.build.jetifier:jetifier-processor:1.0.0-beta09=classpath
-com.android.tools.build:aapt2-proto:7.2.0-7984345=classpath
-com.android.tools.build:aaptcompiler:7.2.0=classpath
-com.android.tools.build:apksig:7.2.0=classpath
-com.android.tools.build:apkzlib:7.2.0=classpath
-com.android.tools.build:builder-model:7.2.0=classpath
-com.android.tools.build:builder-test-api:7.2.0=classpath
-com.android.tools.build:builder:7.2.0=classpath
-com.android.tools.build:bundletool:1.8.2=classpath
-com.android.tools.build:gradle-api:7.2.0=classpath
-com.android.tools.build:gradle:7.2.0=classpath
-com.android.tools.build:manifest-merger:30.2.0=classpath
+androidx.databinding:databinding-common:7.3.0=classpath
+androidx.databinding:databinding-compiler-common:7.3.0=classpath
+com.android.databinding:baseLibrary:7.3.0=classpath
+com.android.tools.analytics-library:crash:30.3.0=classpath
+com.android.tools.analytics-library:protos:30.3.0=classpath
+com.android.tools.analytics-library:shared:30.3.0=classpath
+com.android.tools.analytics-library:tracker:30.3.0=classpath
+com.android.tools.build.jetifier:jetifier-core:1.0.0-beta10=classpath
+com.android.tools.build.jetifier:jetifier-processor:1.0.0-beta10=classpath
+com.android.tools.build:aapt2-proto:7.3.0-8691043=classpath
+com.android.tools.build:aaptcompiler:7.3.0=classpath
+com.android.tools.build:apksig:7.3.0=classpath
+com.android.tools.build:apkzlib:7.3.0=classpath
+com.android.tools.build:builder-model:7.3.0=classpath
+com.android.tools.build:builder-test-api:7.3.0=classpath
+com.android.tools.build:builder:7.3.0=classpath
+com.android.tools.build:bundletool:1.9.0=classpath
+com.android.tools.build:gradle-api:7.3.0=classpath
+com.android.tools.build:gradle:7.3.0=classpath
+com.android.tools.build:manifest-merger:30.3.0=classpath
com.android.tools.build:transform-api:2.0.0-deprecated-use-gradle-api=classpath
-com.android.tools.ddms:ddmlib:30.2.0=classpath
-com.android.tools.layoutlib:layoutlib-api:30.2.0=classpath
-com.android.tools.lint:lint-model:30.2.0=classpath
-com.android.tools.lint:lint-typedef-remover:30.2.0=classpath
-com.android.tools.utp:android-device-provider-ddmlib-proto:30.2.0=classpath
-com.android.tools.utp:android-device-provider-gradle-proto:30.2.0=classpath
-com.android.tools.utp:android-test-plugin-host-additional-test-output-proto:30.2.0=classpath
-com.android.tools.utp:android-test-plugin-host-coverage-proto:30.2.0=classpath
-com.android.tools.utp:android-test-plugin-host-retention-proto:30.2.0=classpath
-com.android.tools.utp:android-test-plugin-result-listener-gradle-proto:30.2.0=classpath
-com.android.tools:annotations:30.2.0=classpath
-com.android.tools:common:30.2.0=classpath
-com.android.tools:dvlib:30.2.0=classpath
-com.android.tools:repository:30.2.0=classpath
-com.android.tools:sdk-common:30.2.0=classpath
-com.android.tools:sdklib:30.2.0=classpath
-com.android:signflinger:7.2.0=classpath
-com.android:zipflinger:7.2.0=classpath
-com.fasterxml.jackson.core:jackson-annotations:2.11.1=classpath
-com.fasterxml.jackson.core:jackson-core:2.11.1=classpath
-com.fasterxml.jackson.core:jackson-databind:2.11.1=classpath
-com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.11.1=classpath
-com.fasterxml.jackson.module:jackson-module-jaxb-annotations:2.11.1=classpath
-com.fasterxml.jackson.module:jackson-module-kotlin:2.11.1=classpath
-com.fasterxml.woodstox:woodstox-core:6.2.1=classpath
+com.android.tools.ddms:ddmlib:30.3.0=classpath
+com.android.tools.layoutlib:layoutlib-api:30.3.0=classpath
+com.android.tools.lint:lint-model:30.3.0=classpath
+com.android.tools.lint:lint-typedef-remover:30.3.0=classpath
+com.android.tools.utp:android-device-provider-ddmlib-proto:30.3.0=classpath
+com.android.tools.utp:android-device-provider-gradle-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-host-additional-test-output-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-host-coverage-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-host-retention-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-result-listener-gradle-proto:30.3.0=classpath
+com.android.tools:annotations:30.3.0=classpath
+com.android.tools:common:30.3.0=classpath
+com.android.tools:dvlib:30.3.0=classpath
+com.android.tools:repository:30.3.0=classpath
+com.android.tools:sdk-common:30.3.0=classpath
+com.android.tools:sdklib:30.3.0=classpath
+com.android:signflinger:7.3.0=classpath
+com.android:zipflinger:7.3.0=classpath
com.github.gundy:semver4j:0.16.4=classpath
com.google.android:annotations:4.1.1.4=classpath
-com.google.api.grpc:proto-google-common-protos:1.12.0=classpath
+com.google.api.grpc:proto-google-common-protos:2.0.1=classpath
com.google.auto.value:auto-value-annotations:1.6.2=classpath
com.google.code.findbugs:jsr305:3.0.2=classpath
-com.google.code.gson:gson:2.8.6=classpath
+com.google.code.gson:gson:2.8.9=classpath
com.google.crypto.tink:tink:1.3.0-rc2=classpath
com.google.dagger:dagger:2.28.3=classpath
-com.google.errorprone:error_prone_annotations:2.3.4=classpath
+com.google.errorprone:error_prone_annotations:2.4.0=classpath
com.google.flatbuffers:flatbuffers-java:1.12.0=classpath
com.google.guava:failureaccess:1.0.1=classpath
com.google.guava:guava:30.1-jre=classpath
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=classpath
com.google.j2objc:j2objc-annotations:1.3=classpath
com.google.jimfs:jimfs:1.1=classpath
-com.google.protobuf:protobuf-java-util:3.10.0=classpath
-com.google.protobuf:protobuf-java:3.10.0=classpath
+com.google.protobuf:protobuf-java-util:3.17.2=classpath
+com.google.protobuf:protobuf-java:3.17.2=classpath
com.google.testing.platform:core-proto:0.0.8-alpha07=classpath
com.googlecode.json-simple:json-simple:1.1=classpath
com.googlecode.juniversalchardet:juniversalchardet:1.0.3=classpath
@@ -76,80 +69,76 @@
commons-io:commons-io:2.4=classpath
commons-logging:commons-logging:1.2=classpath
de.undercouch:gradle-download-task:4.1.1=classpath
-io.grpc:grpc-api:1.21.1=classpath
-io.grpc:grpc-context:1.21.1=classpath
-io.grpc:grpc-core:1.21.1=classpath
-io.grpc:grpc-netty:1.21.1=classpath
-io.grpc:grpc-protobuf-lite:1.21.1=classpath
-io.grpc:grpc-protobuf:1.21.1=classpath
-io.grpc:grpc-stub:1.21.1=classpath
-io.netty:netty-buffer:4.1.34.Final=classpath
-io.netty:netty-codec-http2:4.1.34.Final=classpath
-io.netty:netty-codec-http:4.1.34.Final=classpath
-io.netty:netty-codec-socks:4.1.34.Final=classpath
-io.netty:netty-codec:4.1.34.Final=classpath
-io.netty:netty-common:4.1.34.Final=classpath
-io.netty:netty-handler-proxy:4.1.34.Final=classpath
-io.netty:netty-handler:4.1.34.Final=classpath
-io.netty:netty-resolver:4.1.34.Final=classpath
-io.netty:netty-transport:4.1.34.Final=classpath
-io.opencensus:opencensus-api:0.21.0=classpath
-io.opencensus:opencensus-contrib-grpc-metrics:0.21.0=classpath
+io.grpc:grpc-api:1.39.0=classpath
+io.grpc:grpc-context:1.39.0=classpath
+io.grpc:grpc-core:1.39.0=classpath
+io.grpc:grpc-netty:1.39.0=classpath
+io.grpc:grpc-protobuf-lite:1.39.0=classpath
+io.grpc:grpc-protobuf:1.39.0=classpath
+io.grpc:grpc-stub:1.39.0=classpath
+io.netty:netty-buffer:4.1.52.Final=classpath
+io.netty:netty-codec-http2:4.1.52.Final=classpath
+io.netty:netty-codec-http:4.1.52.Final=classpath
+io.netty:netty-codec-socks:4.1.52.Final=classpath
+io.netty:netty-codec:4.1.52.Final=classpath
+io.netty:netty-common:4.1.52.Final=classpath
+io.netty:netty-handler-proxy:4.1.52.Final=classpath
+io.netty:netty-handler:4.1.52.Final=classpath
+io.netty:netty-resolver:4.1.52.Final=classpath
+io.netty:netty-transport:4.1.52.Final=classpath
+io.perfmark:perfmark-api:0.23.0=classpath
it.unimi.dsi:fastutil:8.4.0=classpath
jakarta.activation:jakarta.activation-api:1.2.1=classpath
jakarta.xml.bind:jakarta.xml.bind-api:2.3.2=classpath
+javax.annotation:javax.annotation-api:1.3.2=classpath
javax.inject:javax.inject:1=classpath
net.java.dev.jna:jna-platform:5.6.0=classpath
net.java.dev.jna:jna:5.6.0=classpath
net.sf.jopt-simple:jopt-simple:4.9=classpath
net.sf.kxml:kxml2:2.3.0=classpath
org.apache.commons:commons-compress:1.20=classpath
-org.apache.httpcomponents:httpclient:4.5.9=classpath
-org.apache.httpcomponents:httpcore:4.4.11=classpath
+org.apache.httpcomponents:httpclient:4.5.13=classpath
+org.apache.httpcomponents:httpcore:4.4.13=classpath
org.apache.httpcomponents:httpmime:4.5.6=classpath
org.bitbucket.b_c:jose4j:0.7.0=classpath
-org.bouncycastle:bcpkix-jdk15on:1.56=classpath
-org.bouncycastle:bcprov-jdk15on:1.56=classpath
+org.bouncycastle:bcpkix-jdk15on:1.67=classpath
+org.bouncycastle:bcprov-jdk15on:1.67=classpath
org.checkerframework:checker-qual:3.5.0=classpath
-org.codehaus.mojo:animal-sniffer-annotations:1.17=classpath
-org.codehaus.woodstox:stax2-api:4.2.1=classpath
+org.codehaus.mojo:animal-sniffer-annotations:1.19=classpath
org.glassfish.jaxb:jaxb-runtime:2.3.2=classpath
org.glassfish.jaxb:txw2:2.3.2=classpath
org.jdom:jdom2:2.0.6=classpath
-org.jetbrains.dokka:dokka-core:1.4.32=classpath
-org.jetbrains.intellij.deps:trove4j:1.0.20181211=classpath
-org.jetbrains.kotlin:kotlin-android-extensions:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-annotation-processing-gradle:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-build-common:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-compiler-embeddable:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-compiler-runner:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-daemon-client:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-daemon-embeddable:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-native-utils:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-project-model:1.5.31=classpath
+org.jetbrains.intellij.deps:trove4j:1.0.20200330=classpath
+org.jetbrains.kotlin:kotlin-android-extensions:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-annotation-processing-gradle:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-build-common:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-compiler-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-compiler-runner:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-daemon-client:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-daemon-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin-idea:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-native-utils:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-project-model:1.7.10=classpath
org.jetbrains.kotlin:kotlin-reflect:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-scripting-common:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-scripting-jvm:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-scripting-common:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-scripting-jvm:1.7.10=classpath
org.jetbrains.kotlin:kotlin-stdlib-common:1.5.31=classpath
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.5.31=classpath
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.31=classpath
org.jetbrains.kotlin:kotlin-stdlib:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-tooling-metadata:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-util-io:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-util-klib:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-tooling-core:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-tooling-metadata:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-util-io:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-util-klib:1.7.10=classpath
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.0=classpath
-org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0=classpath
org.jetbrains:annotations:13.0=classpath
-org.jetbrains:markdown-jvm:0.2.1=classpath
-org.jetbrains:markdown:0.2.1=classpath
org.json:json:20180813=classpath
-org.jsoup:jsoup:1.13.1=classpath
org.jvnet.staxex:stax-ex:1.8.1=classpath
org.ow2.asm:asm-analysis:9.1=classpath
org.ow2.asm:asm-commons:9.1=classpath
diff --git a/dev/integration_tests/flutter_gallery/android/settings.gradle b/dev/integration_tests/flutter_gallery/android/settings.gradle
index 03ae72d..a020595 100644
--- a/dev/integration_tests/flutter_gallery/android/settings.gradle
+++ b/dev/integration_tests/flutter_gallery/android/settings.gradle
@@ -8,8 +8,6 @@
include ':app'
-enableFeaturePreview('ONE_LOCKFILE_PER_PROJECT')
-
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()
diff --git a/dev/integration_tests/flutter_gallery/ios/Runner/Info.plist b/dev/integration_tests/flutter_gallery/ios/Runner/Info.plist
index 14453be..e9a4eea 100644
--- a/dev/integration_tests/flutter_gallery/ios/Runner/Info.plist
+++ b/dev/integration_tests/flutter_gallery/ios/Runner/Info.plist
@@ -41,8 +41,6 @@
</array>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
- <key>UIViewControllerBasedStatusBarAppearance</key>
- <false/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
diff --git a/dev/integration_tests/flutter_gallery/lib/demo/contacts_demo.dart b/dev/integration_tests/flutter_gallery/lib/demo/contacts_demo.dart
index 5890676..70d1a97 100644
--- a/dev/integration_tests/flutter_gallery/lib/demo/contacts_demo.dart
+++ b/dev/integration_tests/flutter_gallery/lib/demo/contacts_demo.dart
@@ -104,6 +104,7 @@
Widget build(BuildContext context) {
return Theme(
data: ThemeData(
+ useMaterial3: false,
brightness: Brightness.light,
primarySwatch: Colors.indigo,
platform: Theme.of(context).platform,
diff --git a/dev/integration_tests/flutter_gallery/lib/gallery/themes.dart b/dev/integration_tests/flutter_gallery/lib/gallery/themes.dart
index 66b7d7a..dbaefed 100644
--- a/dev/integration_tests/flutter_gallery/lib/gallery/themes.dart
+++ b/dev/integration_tests/flutter_gallery/lib/gallery/themes.dart
@@ -26,6 +26,7 @@
background: const Color(0xFF202124),
);
final ThemeData base = ThemeData(
+ useMaterial3: false,
brightness: Brightness.dark,
colorScheme: colorScheme,
primaryColor: primaryColor,
@@ -50,6 +51,7 @@
error: const Color(0xFFB00020),
);
final ThemeData base = ThemeData(
+ useMaterial3: false,
brightness: Brightness.light,
colorScheme: colorScheme,
primaryColor: primaryColor,
diff --git a/dev/integration_tests/flutter_gallery/linux/flutter/generated_plugin_registrant.cc b/dev/integration_tests/flutter_gallery/linux/flutter/generated_plugin_registrant.cc
deleted file mode 100644
index f6f23bf..0000000
--- a/dev/integration_tests/flutter_gallery/linux/flutter/generated_plugin_registrant.cc
+++ /dev/null
@@ -1,15 +0,0 @@
-//
-// Generated file. Do not edit.
-//
-
-// clang-format off
-
-#include "generated_plugin_registrant.h"
-
-#include <url_launcher_linux/url_launcher_plugin.h>
-
-void fl_register_plugins(FlPluginRegistry* registry) {
- g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
- fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
- url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
-}
diff --git a/dev/integration_tests/flutter_gallery/linux/flutter/generated_plugin_registrant.h b/dev/integration_tests/flutter_gallery/linux/flutter/generated_plugin_registrant.h
deleted file mode 100644
index e0f0a47..0000000
--- a/dev/integration_tests/flutter_gallery/linux/flutter/generated_plugin_registrant.h
+++ /dev/null
@@ -1,15 +0,0 @@
-//
-// Generated file. Do not edit.
-//
-
-// clang-format off
-
-#ifndef GENERATED_PLUGIN_REGISTRANT_
-#define GENERATED_PLUGIN_REGISTRANT_
-
-#include <flutter_linux/flutter_linux.h>
-
-// Registers Flutter plugins.
-void fl_register_plugins(FlPluginRegistry* registry);
-
-#endif // GENERATED_PLUGIN_REGISTRANT_
diff --git a/dev/integration_tests/flutter_gallery/linux/flutter/generated_plugins.cmake b/dev/integration_tests/flutter_gallery/linux/flutter/generated_plugins.cmake
deleted file mode 100644
index f16b4c3..0000000
--- a/dev/integration_tests/flutter_gallery/linux/flutter/generated_plugins.cmake
+++ /dev/null
@@ -1,24 +0,0 @@
-#
-# Generated file, do not edit.
-#
-
-list(APPEND FLUTTER_PLUGIN_LIST
- url_launcher_linux
-)
-
-list(APPEND FLUTTER_FFI_PLUGIN_LIST
-)
-
-set(PLUGIN_BUNDLED_LIBRARIES)
-
-foreach(plugin ${FLUTTER_PLUGIN_LIST})
- add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin})
- target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
- list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
- list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
-endforeach(plugin)
-
-foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
- add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin})
- list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
-endforeach(ffi_plugin)
diff --git a/dev/integration_tests/flutter_gallery/pubspec.yaml b/dev/integration_tests/flutter_gallery/pubspec.yaml
index 471f952..39c8696 100644
--- a/dev/integration_tests/flutter_gallery/pubspec.yaml
+++ b/dev/integration_tests/flutter_gallery/pubspec.yaml
@@ -11,7 +11,7 @@
intl: 0.18.1
connectivity: 3.0.6
string_scanner: 1.2.0
- url_launcher: 6.1.11
+ url_launcher: 6.1.12
# This is listed as direct so it can be manually pinned
url_launcher_android: 6.0.17
cupertino_icons: 1.0.5
@@ -34,7 +34,6 @@
csslib: 1.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
device_info_platform_interface: 2.0.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
html: 0.15.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.9.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path: 1.8.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -44,12 +43,13 @@
url_launcher_ios: 6.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
url_launcher_linux: 3.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
url_launcher_macos: 3.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- url_launcher_platform_interface: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- url_launcher_web: 2.0.17 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- url_launcher_windows: 3.0.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ url_launcher_platform_interface: 2.1.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ url_launcher_web: 2.0.18 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ url_launcher_windows: 3.0.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
video_player_platform_interface: 5.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
video_player_web: 2.0.15 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
flutter_test:
@@ -58,18 +58,19 @@
sdk: flutter
flutter_goldens:
sdk: flutter
- test: 1.24.3
+ test: 1.24.4
integration_test:
sdk: flutter
- _fe_analyzer_shared: 61.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- analyzer: 5.13.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ _fe_analyzer_shared: 62.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ analyzer: 6.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
args: 2.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
async: 2.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
convert: 3.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
coverage: 1.6.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
crypto: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ dart_internal: 0.2.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
fake_async: 1.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
file: 6.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
frontend_server_client: 3.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -77,6 +78,7 @@
http_multi_server: 3.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http_parser: 4.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
io: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
logging: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
matcher: 0.12.16 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
mime: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -92,13 +94,13 @@
shelf_web_socket: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_map_stack_trace: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_maps: 0.10.12 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
sync_http: 0.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_core: 0.5.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_core: 0.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- vm_service: 11.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ vm_service: 11.7.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -275,4 +277,4 @@
- asset: packages/flutter_gallery_assets/fonts/merriweather/Merriweather-Regular.ttf
- asset: packages/flutter_gallery_assets/fonts/merriweather/Merriweather-Light.ttf
-# PUBSPEC CHECKSUM: 8d16
+# PUBSPEC CHECKSUM: 9c04
diff --git a/dev/integration_tests/flutter_gallery/test/accessibility_test.dart b/dev/integration_tests/flutter_gallery/test/accessibility_test.dart
index 4bbd3bd..c1d229a 100644
--- a/dev/integration_tests/flutter_gallery/test/accessibility_test.dart
+++ b/dev/integration_tests/flutter_gallery/test/accessibility_test.dart
@@ -8,235 +8,249 @@
import 'package:flutter_gallery/gallery/themes.dart';
import 'package:flutter_test/flutter_test.dart';
+class TestMaterialApp extends StatelessWidget {
+ const TestMaterialApp({ super.key, required this.home });
+
+ final Widget home;
+
+ @override
+ Widget build(BuildContext context) {
+ return MaterialApp(
+ theme: ThemeData(useMaterial3: false),
+ home: home,
+ );
+ }
+}
+
void main() {
group('All material demos meet recommended tap target sizes', () {
testWidgets('backdrop_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: BackdropDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: BackdropDemo()));
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose();
});
testWidgets('bottom_app_bar_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: BottomAppBarDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: BottomAppBarDemo()));
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose();
});
testWidgets('bottom_navigation_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: BottomNavigationDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: BottomNavigationDemo()));
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose();
});
testWidgets('buttons_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: ButtonsDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: ButtonsDemo()));
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose();
});
testWidgets('cards_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: CardsDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: CardsDemo()));
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose();
});
testWidgets('chip_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: ChipDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: ChipDemo()));
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose();
}, skip: true); // https://github.com/flutter/flutter/issues/42455
testWidgets('data_table_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: DataTableDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: DataTableDemo()));
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose();
});
testWidgets('date_and_time_picker_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: DateAndTimePickerDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: DateAndTimePickerDemo()));
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose();
});
testWidgets('dialog_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: DialogDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: DialogDemo()));
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose();
});
testWidgets('drawer_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: DrawerDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: DrawerDemo()));
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose();
});
testWidgets('elevation_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: ElevationDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: ElevationDemo()));
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose();
});
testWidgets('expansion_panels_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: ExpansionPanelsDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: ExpansionPanelsDemo()));
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose();
});
testWidgets('grid_list_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: GridListDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: GridListDemo()));
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose();
});
testWidgets('icons_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: IconsDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: IconsDemo()));
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose();
});
testWidgets('leave_behind_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: LeaveBehindDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: LeaveBehindDemo()));
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose();
});
testWidgets('list_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: ListDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: ListDemo()));
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose();
});
testWidgets('menu_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: MenuDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: MenuDemo()));
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose();
});
testWidgets('modal_bottom_sheet_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: ModalBottomSheetDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: ModalBottomSheetDemo()));
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose();
});
testWidgets('overscroll_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: OverscrollDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: OverscrollDemo()));
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose();
});
testWidgets('page_selector_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: PageSelectorDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: PageSelectorDemo()));
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose();
});
testWidgets('persistent_bottom_sheet_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: PersistentBottomSheetDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: PersistentBottomSheetDemo()));
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose();
});
testWidgets('progress_indicator_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: ProgressIndicatorDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: ProgressIndicatorDemo()));
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose();
});
testWidgets('reorderable_list_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: ReorderableListDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: ReorderableListDemo()));
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose();
});
testWidgets('scrollable_tabs_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: ScrollableTabsDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: ScrollableTabsDemo()));
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose();
});
testWidgets('search_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: SearchDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: SearchDemo()));
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose();
});
testWidgets('selection_controls_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: SelectionControlsDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: SelectionControlsDemo()));
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose();
});
testWidgets('slider_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: SliderDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: SliderDemo()));
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose();
});
testWidgets('snack_bar_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: SnackBarDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: SnackBarDemo()));
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose();
});
testWidgets('tabs_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: TabsDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: TabsDemo()));
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose();
});
testWidgets('tabs_fab_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: TabsFabDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: TabsFabDemo()));
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose();
});
testWidgets('text_form_field_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: TextFormFieldDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: TextFormFieldDemo()));
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose();
});
testWidgets('tooltip_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: TooltipDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: TooltipDemo()));
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose();
});
testWidgets('expansion_tile_list_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: ExpansionTileListDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: ExpansionTileListDemo()));
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
handle.dispose();
});
@@ -245,231 +259,231 @@
group('All material demos have labeled tap targets', () {
testWidgets('backdrop_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: BackdropDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: BackdropDemo()));
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
handle.dispose();
});
testWidgets('bottom_app_bar_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: BottomAppBarDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: BottomAppBarDemo()));
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
handle.dispose();
});
testWidgets('bottom_navigation_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: BottomNavigationDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: BottomNavigationDemo()));
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
handle.dispose();
});
testWidgets('buttons_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: ButtonsDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: ButtonsDemo()));
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
handle.dispose();
});
testWidgets('cards_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: CardsDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: CardsDemo()));
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
handle.dispose();
});
testWidgets('chip_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: ChipDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: ChipDemo()));
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
handle.dispose();
});
testWidgets('data_table_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: DataTableDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: DataTableDemo()));
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
handle.dispose();
}, skip: true); // DataTables are not accessible, https://github.com/flutter/flutter/issues/10830
testWidgets('date_and_time_picker_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: DateAndTimePickerDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: DateAndTimePickerDemo()));
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
handle.dispose();
});
testWidgets('dialog_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: DialogDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: DialogDemo()));
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
handle.dispose();
});
testWidgets('drawer_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: DrawerDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: DrawerDemo()));
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
handle.dispose();
});
testWidgets('elevation_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: ElevationDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: ElevationDemo()));
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
handle.dispose();
});
testWidgets('expansion_panels_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: ExpansionPanelsDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: ExpansionPanelsDemo()));
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
handle.dispose();
});
testWidgets('grid_list_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: GridListDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: GridListDemo()));
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
handle.dispose();
});
testWidgets('icons_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: IconsDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: IconsDemo()));
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
handle.dispose();
});
testWidgets('leave_behind_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: LeaveBehindDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: LeaveBehindDemo()));
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
handle.dispose();
});
testWidgets('list_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: ListDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: ListDemo()));
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
handle.dispose();
});
testWidgets('menu_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: MenuDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: MenuDemo()));
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
handle.dispose();
});
testWidgets('modal_bottom_sheet_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: ModalBottomSheetDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: ModalBottomSheetDemo()));
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
handle.dispose();
});
testWidgets('overscroll_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: OverscrollDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: OverscrollDemo()));
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
handle.dispose();
});
testWidgets('page_selector_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: PageSelectorDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: PageSelectorDemo()));
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
handle.dispose();
});
testWidgets('persistent_bottom_sheet_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: PersistentBottomSheetDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: PersistentBottomSheetDemo()));
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
handle.dispose();
});
testWidgets('progress_indicator_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: ProgressIndicatorDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: ProgressIndicatorDemo()));
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
handle.dispose();
});
testWidgets('reorderable_list_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: ReorderableListDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: ReorderableListDemo()));
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
handle.dispose();
});
testWidgets('scrollable_tabs_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: ScrollableTabsDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: ScrollableTabsDemo()));
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
handle.dispose();
});
testWidgets('search_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: SearchDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: SearchDemo()));
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
handle.dispose();
});
testWidgets('selection_controls_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: SelectionControlsDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: SelectionControlsDemo()));
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
handle.dispose();
});
testWidgets('slider_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: SliderDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: SliderDemo()));
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
handle.dispose();
});
testWidgets('snack_bar_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: SnackBarDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: SnackBarDemo()));
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
handle.dispose();
});
testWidgets('tabs_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: TabsDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: TabsDemo()));
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
handle.dispose();
});
testWidgets('tabs_fab_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: TabsFabDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: TabsFabDemo()));
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
handle.dispose();
});
testWidgets('text_form_field_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: TextFormFieldDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: TextFormFieldDemo()));
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
handle.dispose();
});
testWidgets('tooltip_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: TooltipDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: TooltipDemo()));
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
handle.dispose();
});
testWidgets('expansion_tile_list_demo', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics();
- await tester.pumpWidget(const MaterialApp(home: ExpansionTileListDemo()));
+ await tester.pumpWidget(const TestMaterialApp(home: ExpansionTileListDemo()));
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
handle.dispose();
});
diff --git a/dev/integration_tests/flutter_gallery/test/demo/material/buttons_demo_test.dart b/dev/integration_tests/flutter_gallery/test/demo/material/buttons_demo_test.dart
index a219331..b4faf83 100644
--- a/dev/integration_tests/flutter_gallery/test/demo/material/buttons_demo_test.dart
+++ b/dev/integration_tests/flutter_gallery/test/demo/material/buttons_demo_test.dart
@@ -10,7 +10,7 @@
testWidgets('Button locations are OK', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/pull/85351
{
- await tester.pumpWidget(const MaterialApp(home: ButtonsDemo()));
+ await tester.pumpWidget(MaterialApp(theme: ThemeData(useMaterial3: false), home: const ButtonsDemo()));
expect(find.byType(ElevatedButton).evaluate().length, 2);
final Offset topLeft1 = tester.getTopLeft(find.byType(ElevatedButton).first);
final Offset topLeft2 = tester.getTopLeft(find.byType(ElevatedButton).last);
diff --git a/dev/integration_tests/flutter_gallery/windows/flutter/generated_plugin_registrant.cc b/dev/integration_tests/flutter_gallery/windows/flutter/generated_plugin_registrant.cc
deleted file mode 100644
index 4f78848..0000000
--- a/dev/integration_tests/flutter_gallery/windows/flutter/generated_plugin_registrant.cc
+++ /dev/null
@@ -1,14 +0,0 @@
-//
-// Generated file. Do not edit.
-//
-
-// clang-format off
-
-#include "generated_plugin_registrant.h"
-
-#include <url_launcher_windows/url_launcher_windows.h>
-
-void RegisterPlugins(flutter::PluginRegistry* registry) {
- UrlLauncherWindowsRegisterWithRegistrar(
- registry->GetRegistrarForPlugin("UrlLauncherWindows"));
-}
diff --git a/dev/integration_tests/flutter_gallery/windows/flutter/generated_plugin_registrant.h b/dev/integration_tests/flutter_gallery/windows/flutter/generated_plugin_registrant.h
deleted file mode 100644
index dc139d8..0000000
--- a/dev/integration_tests/flutter_gallery/windows/flutter/generated_plugin_registrant.h
+++ /dev/null
@@ -1,15 +0,0 @@
-//
-// Generated file. Do not edit.
-//
-
-// clang-format off
-
-#ifndef GENERATED_PLUGIN_REGISTRANT_
-#define GENERATED_PLUGIN_REGISTRANT_
-
-#include <flutter/plugin_registry.h>
-
-// Registers Flutter plugins.
-void RegisterPlugins(flutter::PluginRegistry* registry);
-
-#endif // GENERATED_PLUGIN_REGISTRANT_
diff --git a/dev/integration_tests/flutter_gallery/windows/flutter/generated_plugins.cmake b/dev/integration_tests/flutter_gallery/windows/flutter/generated_plugins.cmake
deleted file mode 100644
index 88b22e5..0000000
--- a/dev/integration_tests/flutter_gallery/windows/flutter/generated_plugins.cmake
+++ /dev/null
@@ -1,24 +0,0 @@
-#
-# Generated file, do not edit.
-#
-
-list(APPEND FLUTTER_PLUGIN_LIST
- url_launcher_windows
-)
-
-list(APPEND FLUTTER_FFI_PLUGIN_LIST
-)
-
-set(PLUGIN_BUNDLED_LIBRARIES)
-
-foreach(plugin ${FLUTTER_PLUGIN_LIST})
- add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin})
- target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
- list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
- list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
-endforeach(plugin)
-
-foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
- add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin})
- list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
-endforeach(ffi_plugin)
diff --git a/dev/integration_tests/gradle_deprecated_settings/android/build.gradle b/dev/integration_tests/gradle_deprecated_settings/android/build.gradle
index 57ace36..a2a8866 100644
--- a/dev/integration_tests/gradle_deprecated_settings/android/build.gradle
+++ b/dev/integration_tests/gradle_deprecated_settings/android/build.gradle
@@ -7,14 +7,14 @@
// See dev/tools/bin/generate_gradle_lockfiles.dart.
buildscript {
- ext.kotlin_version = '1.5.31'
+ ext.kotlin_version = '1.7.10'
repositories {
google()
mavenCentral()
}
dependencies {
- classpath 'com.android.tools.build:gradle:4.1.3'
+ classpath 'com.android.tools.build:gradle:7.3.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
diff --git a/dev/integration_tests/gradle_deprecated_settings/android/buildscript-gradle.lockfile b/dev/integration_tests/gradle_deprecated_settings/android/buildscript-gradle.lockfile
index 2577f0a..eb60580 100644
--- a/dev/integration_tests/gradle_deprecated_settings/android/buildscript-gradle.lockfile
+++ b/dev/integration_tests/gradle_deprecated_settings/android/buildscript-gradle.lockfile
@@ -1,120 +1,152 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
-androidx.databinding:databinding-common:4.1.3=classpath
-androidx.databinding:databinding-compiler-common:4.1.3=classpath
-com.android.databinding:baseLibrary:4.1.3=classpath
-com.android.tools.analytics-library:crash:27.1.3=classpath
-com.android.tools.analytics-library:protos:27.1.3=classpath
-com.android.tools.analytics-library:shared:27.1.3=classpath
-com.android.tools.analytics-library:tracker:27.1.3=classpath
-com.android.tools.build.jetifier:jetifier-core:1.0.0-beta09=classpath
-com.android.tools.build.jetifier:jetifier-processor:1.0.0-beta09=classpath
-com.android.tools.build:aapt2-proto:4.1.3-6503028=classpath
-com.android.tools.build:aaptcompiler:4.1.3=classpath
-com.android.tools.build:apksig:4.1.3=classpath
-com.android.tools.build:apkzlib:4.1.3=classpath
-com.android.tools.build:builder-model:4.1.3=classpath
-com.android.tools.build:builder-test-api:4.1.3=classpath
-com.android.tools.build:builder:4.1.3=classpath
-com.android.tools.build:bundletool:0.14.0=classpath
-com.android.tools.build:gradle-api:4.1.3=classpath
-com.android.tools.build:gradle:4.1.3=classpath
-com.android.tools.build:manifest-merger:27.1.3=classpath
+androidx.databinding:databinding-common:7.3.0=classpath
+androidx.databinding:databinding-compiler-common:7.3.0=classpath
+com.android.databinding:baseLibrary:7.3.0=classpath
+com.android.tools.analytics-library:crash:30.3.0=classpath
+com.android.tools.analytics-library:protos:30.3.0=classpath
+com.android.tools.analytics-library:shared:30.3.0=classpath
+com.android.tools.analytics-library:tracker:30.3.0=classpath
+com.android.tools.build.jetifier:jetifier-core:1.0.0-beta10=classpath
+com.android.tools.build.jetifier:jetifier-processor:1.0.0-beta10=classpath
+com.android.tools.build:aapt2-proto:7.3.0-8691043=classpath
+com.android.tools.build:aaptcompiler:7.3.0=classpath
+com.android.tools.build:apksig:7.3.0=classpath
+com.android.tools.build:apkzlib:7.3.0=classpath
+com.android.tools.build:builder-model:7.3.0=classpath
+com.android.tools.build:builder-test-api:7.3.0=classpath
+com.android.tools.build:builder:7.3.0=classpath
+com.android.tools.build:bundletool:1.9.0=classpath
+com.android.tools.build:gradle-api:7.3.0=classpath
+com.android.tools.build:gradle:7.3.0=classpath
+com.android.tools.build:manifest-merger:30.3.0=classpath
com.android.tools.build:transform-api:2.0.0-deprecated-use-gradle-api=classpath
-com.android.tools.ddms:ddmlib:27.1.3=classpath
-com.android.tools.layoutlib:layoutlib-api:27.1.3=classpath
-com.android.tools.lint:lint-gradle-api:27.1.3=classpath
-com.android.tools.lint:lint-model:27.1.3=classpath
-com.android.tools:annotations:27.1.3=classpath
-com.android.tools:common:27.1.3=classpath
-com.android.tools:dvlib:27.1.3=classpath
-com.android.tools:repository:27.1.3=classpath
-com.android.tools:sdk-common:27.1.3=classpath
-com.android.tools:sdklib:27.1.3=classpath
-com.android:signflinger:4.1.3=classpath
-com.android:zipflinger:4.1.3=classpath
+com.android.tools.ddms:ddmlib:30.3.0=classpath
+com.android.tools.layoutlib:layoutlib-api:30.3.0=classpath
+com.android.tools.lint:lint-model:30.3.0=classpath
+com.android.tools.lint:lint-typedef-remover:30.3.0=classpath
+com.android.tools.utp:android-device-provider-ddmlib-proto:30.3.0=classpath
+com.android.tools.utp:android-device-provider-gradle-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-host-additional-test-output-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-host-coverage-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-host-retention-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-result-listener-gradle-proto:30.3.0=classpath
+com.android.tools:annotations:30.3.0=classpath
+com.android.tools:common:30.3.0=classpath
+com.android.tools:dvlib:30.3.0=classpath
+com.android.tools:repository:30.3.0=classpath
+com.android.tools:sdk-common:30.3.0=classpath
+com.android.tools:sdklib:30.3.0=classpath
+com.android:signflinger:7.3.0=classpath
+com.android:zipflinger:7.3.0=classpath
com.github.gundy:semver4j:0.16.4=classpath
+com.google.android:annotations:4.1.1.4=classpath
+com.google.api.grpc:proto-google-common-protos:2.0.1=classpath
com.google.auto.value:auto-value-annotations:1.6.2=classpath
com.google.code.findbugs:jsr305:3.0.2=classpath
-com.google.code.gson:gson:2.8.6=classpath
+com.google.code.gson:gson:2.8.9=classpath
com.google.crypto.tink:tink:1.3.0-rc2=classpath
-com.google.errorprone:error_prone_annotations:2.3.4=classpath
+com.google.dagger:dagger:2.28.3=classpath
+com.google.errorprone:error_prone_annotations:2.4.0=classpath
com.google.flatbuffers:flatbuffers-java:1.12.0=classpath
com.google.guava:failureaccess:1.0.1=classpath
-com.google.guava:guava:29.0-jre=classpath
+com.google.guava:guava:30.1-jre=classpath
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=classpath
com.google.j2objc:j2objc-annotations:1.3=classpath
com.google.jimfs:jimfs:1.1=classpath
-com.google.protobuf:protobuf-java-util:3.10.0=classpath
-com.google.protobuf:protobuf-java:3.10.0=classpath
-com.google.test.platform:core-proto:0.0.2-dev=classpath
+com.google.protobuf:protobuf-java-util:3.17.2=classpath
+com.google.protobuf:protobuf-java:3.17.2=classpath
+com.google.testing.platform:core-proto:0.0.8-alpha07=classpath
com.googlecode.json-simple:json-simple:1.1=classpath
com.googlecode.juniversalchardet:juniversalchardet:1.0.3=classpath
com.squareup:javapoet:1.10.0=classpath
com.squareup:javawriter:2.5.0=classpath
com.sun.activation:javax.activation:1.2.0=classpath
-com.sun.istack:istack-commons-runtime:3.0.7=classpath
-com.sun.xml.fastinfoset:FastInfoset:1.2.15=classpath
-commons-codec:commons-codec:1.10=classpath
+com.sun.istack:istack-commons-runtime:3.0.8=classpath
+com.sun.xml.fastinfoset:FastInfoset:1.2.16=classpath
+commons-codec:commons-codec:1.11=classpath
commons-io:commons-io:2.4=classpath
commons-logging:commons-logging:1.2=classpath
de.undercouch:gradle-download-task:4.1.1=classpath
-it.unimi.dsi:fastutil:7.2.0=classpath
-javax.activation:javax.activation-api:1.2.0=classpath
+io.grpc:grpc-api:1.39.0=classpath
+io.grpc:grpc-context:1.39.0=classpath
+io.grpc:grpc-core:1.39.0=classpath
+io.grpc:grpc-netty:1.39.0=classpath
+io.grpc:grpc-protobuf-lite:1.39.0=classpath
+io.grpc:grpc-protobuf:1.39.0=classpath
+io.grpc:grpc-stub:1.39.0=classpath
+io.netty:netty-buffer:4.1.52.Final=classpath
+io.netty:netty-codec-http2:4.1.52.Final=classpath
+io.netty:netty-codec-http:4.1.52.Final=classpath
+io.netty:netty-codec-socks:4.1.52.Final=classpath
+io.netty:netty-codec:4.1.52.Final=classpath
+io.netty:netty-common:4.1.52.Final=classpath
+io.netty:netty-handler-proxy:4.1.52.Final=classpath
+io.netty:netty-handler:4.1.52.Final=classpath
+io.netty:netty-resolver:4.1.52.Final=classpath
+io.netty:netty-transport:4.1.52.Final=classpath
+io.perfmark:perfmark-api:0.23.0=classpath
+it.unimi.dsi:fastutil:8.4.0=classpath
+jakarta.activation:jakarta.activation-api:1.2.1=classpath
+jakarta.xml.bind:jakarta.xml.bind-api:2.3.2=classpath
+javax.annotation:javax.annotation-api:1.3.2=classpath
javax.inject:javax.inject:1=classpath
-javax.xml.bind:jaxb-api:2.3.1=classpath
+net.java.dev.jna:jna-platform:5.6.0=classpath
+net.java.dev.jna:jna:5.6.0=classpath
net.sf.jopt-simple:jopt-simple:4.9=classpath
net.sf.kxml:kxml2:2.3.0=classpath
-net.sf.proguard:proguard-base:6.0.3=classpath
-net.sf.proguard:proguard-gradle:6.0.3=classpath
-org.antlr:antlr4:4.5.3=classpath
-org.apache.commons:commons-compress:1.12=classpath
-org.apache.httpcomponents:httpclient:4.5.6=classpath
-org.apache.httpcomponents:httpcore:4.4.10=classpath
+org.apache.commons:commons-compress:1.20=classpath
+org.apache.httpcomponents:httpclient:4.5.13=classpath
+org.apache.httpcomponents:httpcore:4.4.13=classpath
org.apache.httpcomponents:httpmime:4.5.6=classpath
-org.bouncycastle:bcpkix-jdk15on:1.56=classpath
-org.bouncycastle:bcprov-jdk15on:1.56=classpath
-org.checkerframework:checker-qual:2.11.1=classpath
-org.glassfish.jaxb:jaxb-runtime:2.3.1=classpath
-org.glassfish.jaxb:txw2:2.3.1=classpath
+org.bitbucket.b_c:jose4j:0.7.0=classpath
+org.bouncycastle:bcpkix-jdk15on:1.67=classpath
+org.bouncycastle:bcprov-jdk15on:1.67=classpath
+org.checkerframework:checker-qual:3.5.0=classpath
+org.codehaus.mojo:animal-sniffer-annotations:1.19=classpath
+org.glassfish.jaxb:jaxb-runtime:2.3.2=classpath
+org.glassfish.jaxb:txw2:2.3.2=classpath
org.jdom:jdom2:2.0.6=classpath
-org.jetbrains.intellij.deps:trove4j:1.0.20181211=classpath
-org.jetbrains.kotlin:kotlin-android-extensions:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-annotation-processing-gradle:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-build-common:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-compiler-embeddable:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-compiler-runner:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-daemon-client:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-daemon-embeddable:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-native-utils:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-project-model:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-reflect:1.3.72=classpath
-org.jetbrains.kotlin:kotlin-scripting-common:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-scripting-jvm:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-stdlib-common:1.3.72=classpath
-org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.72=classpath
-org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.72=classpath
-org.jetbrains.kotlin:kotlin-stdlib:1.3.72=classpath
-org.jetbrains.kotlin:kotlin-tooling-metadata:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-util-io:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-util-klib:1.5.31=classpath
+org.jetbrains.intellij.deps:trove4j:1.0.20200330=classpath
+org.jetbrains.kotlin:kotlin-android-extensions:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-annotation-processing-gradle:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-build-common:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-compiler-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-compiler-runner:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-daemon-client:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-daemon-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin-idea:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-native-utils:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-project-model:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-reflect:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-scripting-common:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-scripting-jvm:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-stdlib-common:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-stdlib:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-tooling-core:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-tooling-metadata:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-util-io:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-util-klib:1.7.10=classpath
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.0=classpath
-org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0=classpath
-org.jetbrains.trove4j:trove4j:20160824=classpath
org.jetbrains:annotations:13.0=classpath
org.json:json:20180813=classpath
-org.jvnet.staxex:stax-ex:1.8=classpath
-org.ow2.asm:asm-analysis:7.0=classpath
-org.ow2.asm:asm-commons:7.0=classpath
-org.ow2.asm:asm-tree:7.0=classpath
-org.ow2.asm:asm-util:7.0=classpath
-org.ow2.asm:asm:7.0=classpath
-org.tensorflow:tensorflow-lite-metadata:0.1.0-rc1=classpath
+org.jvnet.staxex:stax-ex:1.8.1=classpath
+org.ow2.asm:asm-analysis:9.1=classpath
+org.ow2.asm:asm-commons:9.1=classpath
+org.ow2.asm:asm-tree:9.1=classpath
+org.ow2.asm:asm-util:9.1=classpath
+org.ow2.asm:asm:9.1=classpath
+org.slf4j:slf4j-api:1.7.30=classpath
+org.tensorflow:tensorflow-lite-metadata:0.1.0-rc2=classpath
+xerces:xercesImpl:2.12.0=classpath
+xml-apis:xml-apis:1.4.01=classpath
empty=
diff --git a/dev/integration_tests/gradle_deprecated_settings/android/project-app.lockfile b/dev/integration_tests/gradle_deprecated_settings/android/project-app.lockfile
index 1572e4b..04eea48 100644
--- a/dev/integration_tests/gradle_deprecated_settings/android/project-app.lockfile
+++ b/dev/integration_tests/gradle_deprecated_settings/android/project-app.lockfile
@@ -88,6 +88,10 @@
org.codehaus.mojo:animal-sniffer-annotations:1.18=lintClassPath
org.glassfish.jaxb:jaxb-runtime:2.3.1=lintClassPath
org.glassfish.jaxb:txw2:2.3.1=lintClassPath
+org.jacoco:org.jacoco.agent:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.ant:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.core:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.report:0.8.7=androidJacocoAnt
org.jetbrains.kotlin:kotlin-reflect:1.3.72=lintClassPath
org.jetbrains.kotlin:kotlin-stdlib-common:1.3.72=lintClassPath
org.jetbrains.kotlin:kotlin-stdlib-common:1.5.31=debugAndroidTestCompileClasspath
@@ -106,8 +110,12 @@
org.jetbrains:annotations:13.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,lintClassPath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.jvnet.staxex:stax-ex:1.8=lintClassPath
org.ow2.asm:asm-analysis:7.0=lintClassPath
+org.ow2.asm:asm-analysis:9.1=androidJacocoAnt
org.ow2.asm:asm-commons:7.0=lintClassPath
+org.ow2.asm:asm-commons:9.1=androidJacocoAnt
org.ow2.asm:asm-tree:7.0=lintClassPath
+org.ow2.asm:asm-tree:9.1=androidJacocoAnt
org.ow2.asm:asm-util:7.0=lintClassPath
org.ow2.asm:asm:7.0=lintClassPath
-empty=androidApis,androidTestUtil,compile,coreLibraryDesugaring,debugAndroidTestAnnotationProcessorClasspath,debugAndroidTestRuntimeClasspath,debugAnnotationProcessorClasspath,debugReverseMetadataValues,debugUnitTestAnnotationProcessorClasspath,debugWearBundling,lintChecks,lintPublish,profileAnnotationProcessorClasspath,profileReverseMetadataValues,profileUnitTestAnnotationProcessorClasspath,profileWearBundling,releaseAnnotationProcessorClasspath,releaseReverseMetadataValues,releaseUnitTestAnnotationProcessorClasspath,releaseWearBundling,testCompile
+org.ow2.asm:asm:9.1=androidJacocoAnt
+empty=androidApis,androidJdkImage,androidTestUtil,compile,coreLibraryDesugaring,debugAndroidTestAnnotationProcessorClasspath,debugAndroidTestRuntimeClasspath,debugAnnotationProcessorClasspath,debugReverseMetadataValues,debugUnitTestAnnotationProcessorClasspath,debugWearBundling,lintChecks,lintPublish,profileAnnotationProcessorClasspath,profileReverseMetadataValues,profileUnitTestAnnotationProcessorClasspath,profileWearBundling,releaseAnnotationProcessorClasspath,releaseReverseMetadataValues,releaseUnitTestAnnotationProcessorClasspath,releaseWearBundling,testCompile
diff --git a/dev/integration_tests/gradle_deprecated_settings/android/project-flutter_plugin_android_lifecycle.lockfile b/dev/integration_tests/gradle_deprecated_settings/android/project-flutter_plugin_android_lifecycle.lockfile
index 28354d0..6b4d3af 100644
--- a/dev/integration_tests/gradle_deprecated_settings/android/project-flutter_plugin_android_lifecycle.lockfile
+++ b/dev/integration_tests/gradle_deprecated_settings/android/project-flutter_plugin_android_lifecycle.lockfile
@@ -91,6 +91,10 @@
org.glassfish.jaxb:jaxb-runtime:2.3.1=lintClassPath
org.glassfish.jaxb:txw2:2.3.1=lintClassPath
org.hamcrest:hamcrest-core:1.3=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jacoco:org.jacoco.agent:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.ant:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.core:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.report:0.8.7=androidJacocoAnt
org.jetbrains.kotlin:kotlin-reflect:1.3.72=lintClassPath
org.jetbrains.kotlin:kotlin-stdlib-common:1.3.72=lintClassPath
org.jetbrains.kotlin:kotlin-stdlib-common:1.7.10=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
@@ -109,8 +113,12 @@
org.mockito:mockito-core:5.1.1=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.objenesis:objenesis:3.3=debugUnitTestRuntimeClasspath,profileUnitTestRuntimeClasspath,releaseUnitTestRuntimeClasspath
org.ow2.asm:asm-analysis:7.0=lintClassPath
+org.ow2.asm:asm-analysis:9.1=androidJacocoAnt
org.ow2.asm:asm-commons:7.0=lintClassPath
+org.ow2.asm:asm-commons:9.1=androidJacocoAnt
org.ow2.asm:asm-tree:7.0=lintClassPath
+org.ow2.asm:asm-tree:9.1=androidJacocoAnt
org.ow2.asm:asm-util:7.0=lintClassPath
org.ow2.asm:asm:7.0=lintClassPath
-empty=androidApis,androidTestUtil,compile,coreLibraryDesugaring,debugAndroidTestAnnotationProcessorClasspath,debugAnnotationProcessorClasspath,debugUnitTestAnnotationProcessorClasspath,lintChecks,lintPublish,profileAnnotationProcessorClasspath,profileUnitTestAnnotationProcessorClasspath,releaseAnnotationProcessorClasspath,releaseUnitTestAnnotationProcessorClasspath,testCompile
+org.ow2.asm:asm:9.1=androidJacocoAnt
+empty=androidApis,androidJdkImage,androidTestUtil,compile,coreLibraryDesugaring,debugAndroidTestAnnotationProcessorClasspath,debugAnnotationProcessorClasspath,debugUnitTestAnnotationProcessorClasspath,lintChecks,lintPublish,profileAnnotationProcessorClasspath,profileUnitTestAnnotationProcessorClasspath,releaseAnnotationProcessorClasspath,releaseUnitTestAnnotationProcessorClasspath,testCompile
diff --git a/dev/integration_tests/gradle_deprecated_settings/android/settings.gradle b/dev/integration_tests/gradle_deprecated_settings/android/settings.gradle
index 03ae72d..a020595 100644
--- a/dev/integration_tests/gradle_deprecated_settings/android/settings.gradle
+++ b/dev/integration_tests/gradle_deprecated_settings/android/settings.gradle
@@ -8,8 +8,6 @@
include ':app'
-enableFeaturePreview('ONE_LOCKFILE_PER_PROJECT')
-
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()
diff --git a/dev/integration_tests/gradle_deprecated_settings/pubspec.yaml b/dev/integration_tests/gradle_deprecated_settings/pubspec.yaml
index 6c49f43..0cff6ce 100644
--- a/dev/integration_tests/gradle_deprecated_settings/pubspec.yaml
+++ b/dev/integration_tests/gradle_deprecated_settings/pubspec.yaml
@@ -11,7 +11,7 @@
async: 2.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- camera_android: 0.10.8+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ camera_android: 0.10.8+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
camera_avfoundation: 0.9.13+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
camera_platform_interface: 2.5.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
camera_web: 0.3.1+4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -27,15 +27,16 @@
plugin_platform_interface: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
quiver: 3.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
stream_transform: 2.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
flutter:
uses-material-design: true
-# PUBSPEC CHECKSUM: 5ea8
+# PUBSPEC CHECKSUM: bf03
diff --git a/dev/integration_tests/hybrid_android_views/android/build.gradle b/dev/integration_tests/hybrid_android_views/android/build.gradle
index d3c7bfb..a2a8866 100644
--- a/dev/integration_tests/hybrid_android_views/android/build.gradle
+++ b/dev/integration_tests/hybrid_android_views/android/build.gradle
@@ -7,14 +7,14 @@
// See dev/tools/bin/generate_gradle_lockfiles.dart.
buildscript {
- ext.kotlin_version = '1.6.21'
+ ext.kotlin_version = '1.7.10'
repositories {
google()
mavenCentral()
}
dependencies {
- classpath 'com.android.tools.build:gradle:7.4.2'
+ classpath 'com.android.tools.build:gradle:7.3.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
diff --git a/dev/integration_tests/hybrid_android_views/android/buildscript-gradle.lockfile b/dev/integration_tests/hybrid_android_views/android/buildscript-gradle.lockfile
index 814eb13..eb60580 100644
--- a/dev/integration_tests/hybrid_android_views/android/buildscript-gradle.lockfile
+++ b/dev/integration_tests/hybrid_android_views/android/buildscript-gradle.lockfile
@@ -1,46 +1,45 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
-androidx.databinding:databinding-common:7.4.2=classpath
-androidx.databinding:databinding-compiler-common:7.4.2=classpath
-com.android.databinding:baseLibrary:7.4.2=classpath
-com.android.tools.analytics-library:crash:30.4.2=classpath
-com.android.tools.analytics-library:protos:30.4.2=classpath
-com.android.tools.analytics-library:shared:30.4.2=classpath
-com.android.tools.analytics-library:tracker:30.4.2=classpath
+androidx.databinding:databinding-common:7.3.0=classpath
+androidx.databinding:databinding-compiler-common:7.3.0=classpath
+com.android.databinding:baseLibrary:7.3.0=classpath
+com.android.tools.analytics-library:crash:30.3.0=classpath
+com.android.tools.analytics-library:protos:30.3.0=classpath
+com.android.tools.analytics-library:shared:30.3.0=classpath
+com.android.tools.analytics-library:tracker:30.3.0=classpath
com.android.tools.build.jetifier:jetifier-core:1.0.0-beta10=classpath
com.android.tools.build.jetifier:jetifier-processor:1.0.0-beta10=classpath
-com.android.tools.build:aapt2-proto:7.4.2-8841542=classpath
-com.android.tools.build:aaptcompiler:7.4.2=classpath
-com.android.tools.build:apksig:7.4.2=classpath
-com.android.tools.build:apkzlib:7.4.2=classpath
-com.android.tools.build:builder-model:7.4.2=classpath
-com.android.tools.build:builder-test-api:7.4.2=classpath
-com.android.tools.build:builder:7.4.2=classpath
-com.android.tools.build:bundletool:1.11.4=classpath
-com.android.tools.build:gradle-api:7.4.2=classpath
-com.android.tools.build:gradle-settings-api:7.4.2=classpath
-com.android.tools.build:gradle:7.4.2=classpath
-com.android.tools.build:manifest-merger:30.4.2=classpath
+com.android.tools.build:aapt2-proto:7.3.0-8691043=classpath
+com.android.tools.build:aaptcompiler:7.3.0=classpath
+com.android.tools.build:apksig:7.3.0=classpath
+com.android.tools.build:apkzlib:7.3.0=classpath
+com.android.tools.build:builder-model:7.3.0=classpath
+com.android.tools.build:builder-test-api:7.3.0=classpath
+com.android.tools.build:builder:7.3.0=classpath
+com.android.tools.build:bundletool:1.9.0=classpath
+com.android.tools.build:gradle-api:7.3.0=classpath
+com.android.tools.build:gradle:7.3.0=classpath
+com.android.tools.build:manifest-merger:30.3.0=classpath
com.android.tools.build:transform-api:2.0.0-deprecated-use-gradle-api=classpath
-com.android.tools.ddms:ddmlib:30.4.2=classpath
-com.android.tools.layoutlib:layoutlib-api:30.4.2=classpath
-com.android.tools.lint:lint-model:30.4.2=classpath
-com.android.tools.lint:lint-typedef-remover:30.4.2=classpath
-com.android.tools.utp:android-device-provider-ddmlib-proto:30.4.2=classpath
-com.android.tools.utp:android-device-provider-gradle-proto:30.4.2=classpath
-com.android.tools.utp:android-test-plugin-host-additional-test-output-proto:30.4.2=classpath
-com.android.tools.utp:android-test-plugin-host-coverage-proto:30.4.2=classpath
-com.android.tools.utp:android-test-plugin-host-retention-proto:30.4.2=classpath
-com.android.tools.utp:android-test-plugin-result-listener-gradle-proto:30.4.2=classpath
-com.android.tools:annotations:30.4.2=classpath
-com.android.tools:common:30.4.2=classpath
-com.android.tools:dvlib:30.4.2=classpath
-com.android.tools:repository:30.4.2=classpath
-com.android.tools:sdk-common:30.4.2=classpath
-com.android.tools:sdklib:30.4.2=classpath
-com.android:signflinger:7.4.2=classpath
-com.android:zipflinger:7.4.2=classpath
+com.android.tools.ddms:ddmlib:30.3.0=classpath
+com.android.tools.layoutlib:layoutlib-api:30.3.0=classpath
+com.android.tools.lint:lint-model:30.3.0=classpath
+com.android.tools.lint:lint-typedef-remover:30.3.0=classpath
+com.android.tools.utp:android-device-provider-ddmlib-proto:30.3.0=classpath
+com.android.tools.utp:android-device-provider-gradle-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-host-additional-test-output-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-host-coverage-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-host-retention-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-result-listener-gradle-proto:30.3.0=classpath
+com.android.tools:annotations:30.3.0=classpath
+com.android.tools:common:30.3.0=classpath
+com.android.tools:dvlib:30.3.0=classpath
+com.android.tools:repository:30.3.0=classpath
+com.android.tools:sdk-common:30.3.0=classpath
+com.android.tools:sdklib:30.3.0=classpath
+com.android:signflinger:7.3.0=classpath
+com.android:zipflinger:7.3.0=classpath
com.github.gundy:semver4j:0.16.4=classpath
com.google.android:annotations:4.1.1.4=classpath
com.google.api.grpc:proto-google-common-protos:2.0.1=classpath
@@ -58,7 +57,8 @@
com.google.jimfs:jimfs:1.1=classpath
com.google.protobuf:protobuf-java-util:3.17.2=classpath
com.google.protobuf:protobuf-java:3.17.2=classpath
-com.google.testing.platform:core-proto:0.0.8-alpha08=classpath
+com.google.testing.platform:core-proto:0.0.8-alpha07=classpath
+com.googlecode.json-simple:json-simple:1.1=classpath
com.googlecode.juniversalchardet:juniversalchardet:1.0.3=classpath
com.squareup:javapoet:1.10.0=classpath
com.squareup:javawriter:2.5.0=classpath
@@ -87,6 +87,7 @@
io.netty:netty-resolver:4.1.52.Final=classpath
io.netty:netty-transport:4.1.52.Final=classpath
io.perfmark:perfmark-api:0.23.0=classpath
+it.unimi.dsi:fastutil:8.4.0=classpath
jakarta.activation:jakarta.activation-api:1.2.1=classpath
jakarta.xml.bind:jakarta.xml.bind-api:2.3.2=classpath
javax.annotation:javax.annotation-api:1.3.2=classpath
@@ -108,40 +109,42 @@
org.glassfish.jaxb:txw2:2.3.2=classpath
org.jdom:jdom2:2.0.6=classpath
org.jetbrains.intellij.deps:trove4j:1.0.20200330=classpath
-org.jetbrains.kotlin:kotlin-android-extensions:1.6.21=classpath
-org.jetbrains.kotlin:kotlin-annotation-processing-gradle:1.6.21=classpath
-org.jetbrains.kotlin:kotlin-build-common:1.6.21=classpath
-org.jetbrains.kotlin:kotlin-compiler-embeddable:1.6.21=classpath
-org.jetbrains.kotlin:kotlin-compiler-runner:1.6.21=classpath
-org.jetbrains.kotlin:kotlin-daemon-client:1.6.21=classpath
-org.jetbrains.kotlin:kotlin-daemon-embeddable:1.6.21=classpath
-org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.6.21=classpath
-org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.6.21=classpath
-org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.21=classpath
-org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.6.21=classpath
-org.jetbrains.kotlin:kotlin-native-utils:1.6.21=classpath
-org.jetbrains.kotlin:kotlin-project-model:1.6.21=classpath
-org.jetbrains.kotlin:kotlin-reflect:1.7.10=classpath
-org.jetbrains.kotlin:kotlin-scripting-common:1.6.21=classpath
-org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.6.21=classpath
-org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.6.21=classpath
-org.jetbrains.kotlin:kotlin-scripting-jvm:1.6.21=classpath
-org.jetbrains.kotlin:kotlin-stdlib-common:1.7.10=classpath
-org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.10=classpath
-org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.10=classpath
-org.jetbrains.kotlin:kotlin-stdlib:1.7.10=classpath
-org.jetbrains.kotlin:kotlin-tooling-metadata:1.6.21=classpath
-org.jetbrains.kotlin:kotlin-util-io:1.6.21=classpath
-org.jetbrains.kotlin:kotlin-util-klib:1.6.21=classpath
+org.jetbrains.kotlin:kotlin-android-extensions:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-annotation-processing-gradle:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-build-common:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-compiler-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-compiler-runner:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-daemon-client:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-daemon-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin-idea:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-native-utils:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-project-model:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-reflect:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-scripting-common:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-scripting-jvm:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-stdlib-common:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-stdlib:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-tooling-core:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-tooling-metadata:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-util-io:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-util-klib:1.7.10=classpath
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.0=classpath
org.jetbrains:annotations:13.0=classpath
org.json:json:20180813=classpath
org.jvnet.staxex:stax-ex:1.8.1=classpath
-org.ow2.asm:asm-analysis:9.2=classpath
-org.ow2.asm:asm-commons:9.2=classpath
-org.ow2.asm:asm-tree:9.2=classpath
-org.ow2.asm:asm-util:9.2=classpath
-org.ow2.asm:asm:9.2=classpath
+org.ow2.asm:asm-analysis:9.1=classpath
+org.ow2.asm:asm-commons:9.1=classpath
+org.ow2.asm:asm-tree:9.1=classpath
+org.ow2.asm:asm-util:9.1=classpath
+org.ow2.asm:asm:9.1=classpath
org.slf4j:slf4j-api:1.7.30=classpath
org.tensorflow:tensorflow-lite-metadata:0.1.0-rc2=classpath
xerces:xercesImpl:2.12.0=classpath
diff --git a/dev/integration_tests/hybrid_android_views/android/project-app.lockfile b/dev/integration_tests/hybrid_android_views/android/project-app.lockfile
index 9592202..04eea48 100644
--- a/dev/integration_tests/hybrid_android_views/android/project-app.lockfile
+++ b/dev/integration_tests/hybrid_android_views/android/project-app.lockfile
@@ -55,14 +55,13 @@
com.android.tools:sdklib:27.1.3=lintClassPath
com.android:signflinger:4.1.3=lintClassPath
com.android:zipflinger:4.1.3=lintClassPath
-com.google.code.findbugs:jsr305:3.0.2=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,lintClassPath,profileRuntimeClasspath,profileUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath
+com.google.code.findbugs:jsr305:3.0.2=lintClassPath
com.google.code.gson:gson:2.8.5=lintClassPath
-com.google.errorprone:error_prone_annotations:2.3.2=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,lintClassPath,profileRuntimeClasspath,profileUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath
-com.google.guava:failureaccess:1.0.1=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,lintClassPath,profileRuntimeClasspath,profileUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath
-com.google.guava:guava:28.1-android=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,profileRuntimeClasspath,profileUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath
+com.google.errorprone:error_prone_annotations:2.3.2=lintClassPath
+com.google.guava:failureaccess:1.0.1=lintClassPath
com.google.guava:guava:28.1-jre=lintClassPath
-com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,lintClassPath,profileRuntimeClasspath,profileUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath
-com.google.j2objc:j2objc-annotations:1.3=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,lintClassPath,profileRuntimeClasspath,profileUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath
+com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=lintClassPath
+com.google.j2objc:j2objc-annotations:1.3=lintClassPath
com.google.jimfs:jimfs:1.1=lintClassPath
com.google.protobuf:protobuf-java:3.10.0=lintClassPath
com.googlecode.json-simple:json-simple:1.1=lintClassPath
@@ -84,16 +83,15 @@
org.apache.httpcomponents:httpmime:4.5.6=lintClassPath
org.bouncycastle:bcpkix-jdk15on:1.56=lintClassPath
org.bouncycastle:bcprov-jdk15on:1.56=lintClassPath
-org.checkerframework:checker-compat-qual:2.5.5=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,profileRuntimeClasspath,profileUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath
org.checkerframework:checker-qual:2.8.1=lintClassPath
org.codehaus.groovy:groovy-all:2.4.15=lintClassPath
-org.codehaus.mojo:animal-sniffer-annotations:1.18=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,lintClassPath,profileRuntimeClasspath,profileUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath
+org.codehaus.mojo:animal-sniffer-annotations:1.18=lintClassPath
org.glassfish.jaxb:jaxb-runtime:2.3.1=lintClassPath
org.glassfish.jaxb:txw2:2.3.1=lintClassPath
-org.jacoco:org.jacoco.agent:0.8.8=androidJacocoAnt
-org.jacoco:org.jacoco.ant:0.8.8=androidJacocoAnt
-org.jacoco:org.jacoco.core:0.8.8=androidJacocoAnt
-org.jacoco:org.jacoco.report:0.8.8=androidJacocoAnt
+org.jacoco:org.jacoco.agent:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.ant:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.core:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.report:0.8.7=androidJacocoAnt
org.jetbrains.kotlin:kotlin-reflect:1.3.72=lintClassPath
org.jetbrains.kotlin:kotlin-stdlib-common:1.3.72=lintClassPath
org.jetbrains.kotlin:kotlin-stdlib-common:1.5.31=debugAndroidTestCompileClasspath
@@ -112,12 +110,12 @@
org.jetbrains:annotations:13.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,lintClassPath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.jvnet.staxex:stax-ex:1.8=lintClassPath
org.ow2.asm:asm-analysis:7.0=lintClassPath
-org.ow2.asm:asm-analysis:9.2=androidJacocoAnt
+org.ow2.asm:asm-analysis:9.1=androidJacocoAnt
org.ow2.asm:asm-commons:7.0=lintClassPath
-org.ow2.asm:asm-commons:9.2=androidJacocoAnt
+org.ow2.asm:asm-commons:9.1=androidJacocoAnt
org.ow2.asm:asm-tree:7.0=lintClassPath
-org.ow2.asm:asm-tree:9.2=androidJacocoAnt
+org.ow2.asm:asm-tree:9.1=androidJacocoAnt
org.ow2.asm:asm-util:7.0=lintClassPath
org.ow2.asm:asm:7.0=lintClassPath
-org.ow2.asm:asm:9.2=androidJacocoAnt
+org.ow2.asm:asm:9.1=androidJacocoAnt
empty=androidApis,androidJdkImage,androidTestUtil,compile,coreLibraryDesugaring,debugAndroidTestAnnotationProcessorClasspath,debugAndroidTestRuntimeClasspath,debugAnnotationProcessorClasspath,debugReverseMetadataValues,debugUnitTestAnnotationProcessorClasspath,debugWearBundling,lintChecks,lintPublish,profileAnnotationProcessorClasspath,profileReverseMetadataValues,profileUnitTestAnnotationProcessorClasspath,profileWearBundling,releaseAnnotationProcessorClasspath,releaseReverseMetadataValues,releaseUnitTestAnnotationProcessorClasspath,releaseWearBundling,testCompile
diff --git a/dev/integration_tests/hybrid_android_views/android/project-path_provider_android.lockfile b/dev/integration_tests/hybrid_android_views/android/project-path_provider_android.lockfile
new file mode 100644
index 0000000..2578824
--- /dev/null
+++ b/dev/integration_tests/hybrid_android_views/android/project-path_provider_android.lockfile
@@ -0,0 +1,44 @@
+# This is a Gradle generated file for dependency locking.
+# Manual edits can break the build and are not advised.
+# This file is expected to be part of source control.
+androidx.activity:activity:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.annotation:annotation-experimental:1.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.annotation:annotation:1.5.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.arch.core:core-common:2.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.arch.core:core-runtime:2.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.collection:collection:1.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.core:core:1.6.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.customview:customview:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.fragment:fragment:1.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.lifecycle:lifecycle-common-java8:2.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.lifecycle:lifecycle-common:2.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.lifecycle:lifecycle-livedata-core:2.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.lifecycle:lifecycle-livedata:2.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.lifecycle:lifecycle-runtime:2.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.lifecycle:lifecycle-viewmodel:2.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.loader:loader:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.savedstate:savedstate:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.tracing:tracing:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.versionedparcelable:versionedparcelable:1.1.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.viewpager:viewpager:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.window:window-java:1.0.0-beta04=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.window:window:1.0.0-beta04=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+junit:junit:4.13.2=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.hamcrest:hamcrest-core:1.3=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jacoco:org.jacoco.agent:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.ant:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.core:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.report:0.8.7=androidJacocoAnt
+org.jetbrains.kotlin:kotlin-stdlib-common:1.7.10=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.5.30=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.30=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlin:kotlin-stdlib:1.7.10=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains:annotations:13.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.ow2.asm:asm-analysis:9.1=androidJacocoAnt
+org.ow2.asm:asm-commons:9.1=androidJacocoAnt
+org.ow2.asm:asm-tree:9.1=androidJacocoAnt
+org.ow2.asm:asm:9.1=androidJacocoAnt
+empty=androidApis,androidJdkImage,androidTestUtil,coreLibraryDesugaring,debugAndroidTestAnnotationProcessorClasspath,debugAnnotationProcessorClasspath,debugUnitTestAnnotationProcessorClasspath,lintChecks,lintPublish,profileAnnotationProcessorClasspath,profileUnitTestAnnotationProcessorClasspath,releaseAnnotationProcessorClasspath,releaseUnitTestAnnotationProcessorClasspath
diff --git a/dev/integration_tests/hybrid_android_views/android/settings.gradle b/dev/integration_tests/hybrid_android_views/android/settings.gradle
index 03ae72d..a020595 100644
--- a/dev/integration_tests/hybrid_android_views/android/settings.gradle
+++ b/dev/integration_tests/hybrid_android_views/android/settings.gradle
@@ -8,8 +8,6 @@
include ':app'
-enableFeaturePreview('ONE_LOCKFILE_PER_PROJECT')
-
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()
diff --git a/dev/integration_tests/hybrid_android_views/pubspec.yaml b/dev/integration_tests/hybrid_android_views/pubspec.yaml
index e233359..e80ef4b 100644
--- a/dev/integration_tests/hybrid_android_views/pubspec.yaml
+++ b/dev/integration_tests/hybrid_android_views/pubspec.yaml
@@ -24,12 +24,11 @@
characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
ffi: 2.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
file: 6.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
matcher: 0.12.16 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.9.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path: 1.8.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- path_provider_android: 2.0.21 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ path_provider_android: 2.0.27 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path_provider_foundation: 2.2.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path_provider_linux: 2.1.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path_provider_platform_interface: 2.0.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -38,36 +37,39 @@
plugin_platform_interface: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
process: 4.2.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
sync_http: 0.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- vm_service: 11.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ vm_service: 11.7.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- win32: 5.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ win32: 5.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
xdg_directories: 1.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
flutter_test:
sdk: flutter
- test: 1.24.3
+ test: 1.24.4
- _fe_analyzer_shared: 61.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- analyzer: 5.13.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ _fe_analyzer_shared: 62.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ analyzer: 6.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
args: 2.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
clock: 1.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
convert: 3.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
coverage: 1.6.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
crypto: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ dart_internal: 0.2.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
fake_async: 1.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
frontend_server_client: 3.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
glob: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http_multi_server: 3.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http_parser: 4.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
io: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
logging: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
mime: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
node_preamble: 2.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -80,7 +82,7 @@
shelf_web_socket: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_map_stack_trace: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_maps: 0.10.12 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_core: 0.5.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_core: 0.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -90,4 +92,4 @@
flutter:
uses-material-design: true
-# PUBSPEC CHECKSUM: 8c17
+# PUBSPEC CHECKSUM: ae09
diff --git a/dev/integration_tests/ios_add2app_life_cycle/flutterapp/pubspec.yaml b/dev/integration_tests/ios_add2app_life_cycle/flutterapp/pubspec.yaml
index 3cb1e46..d7c0aa5 100644
--- a/dev/integration_tests/ios_add2app_life_cycle/flutterapp/pubspec.yaml
+++ b/dev/integration_tests/ios_add2app_life_cycle/flutterapp/pubspec.yaml
@@ -26,10 +26,10 @@
characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
collection: 1.17.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.9.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
flutter_test:
@@ -45,11 +45,11 @@
matcher: 0.12.16 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path: 1.8.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
flutter:
# The following line ensures that the Material Icons font is
@@ -99,4 +99,4 @@
androidPackage: com.example.iosadd2appflutter
iosBundleIdentifier: com.example.iosAdd2appFlutter
-# PUBSPEC CHECKSUM: 3dc5
+# PUBSPEC CHECKSUM: beec
diff --git a/dev/integration_tests/ios_app_with_extensions/ios/Runner/Info.plist b/dev/integration_tests/ios_app_with_extensions/ios/Runner/Info.plist
index e8dc95f..d6edc2b 100644
--- a/dev/integration_tests/ios_app_with_extensions/ios/Runner/Info.plist
+++ b/dev/integration_tests/ios_app_with_extensions/ios/Runner/Info.plist
@@ -39,8 +39,6 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
- <key>UIViewControllerBasedStatusBarAppearance</key>
- <false/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
diff --git a/dev/integration_tests/ios_app_with_extensions/pubspec.yaml b/dev/integration_tests/ios_app_with_extensions/pubspec.yaml
index 03db192..08cab7f 100644
--- a/dev/integration_tests/ios_app_with_extensions/pubspec.yaml
+++ b/dev/integration_tests/ios_app_with_extensions/pubspec.yaml
@@ -25,11 +25,11 @@
characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
collection: 1.17.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
device_info_platform_interface: 2.0.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.9.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
plugin_platform_interface: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
flutter_test:
@@ -47,11 +47,11 @@
matcher: 0.12.16 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path: 1.8.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
flutter:
@@ -91,4 +91,4 @@
# For details regarding fonts from package dependencies,
# see https://flutter.dev/custom-fonts/#from-packages
-# PUBSPEC CHECKSUM: 474b
+# PUBSPEC CHECKSUM: b172
diff --git a/dev/integration_tests/ios_platform_view_tests/ios/Runner/Info.plist b/dev/integration_tests/ios_platform_view_tests/ios/Runner/Info.plist
index 2fb9614..9f9045b 100644
--- a/dev/integration_tests/ios_platform_view_tests/ios/Runner/Info.plist
+++ b/dev/integration_tests/ios_platform_view_tests/ios/Runner/Info.plist
@@ -39,8 +39,6 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
- <key>UIViewControllerBasedStatusBarAppearance</key>
- <false/>
<key>io.flutter.embedded_views_preview</key>
<true/>
<key>CADisableMinimumFrameDurationOnPhone</key>
diff --git a/dev/integration_tests/ios_platform_view_tests/pubspec.yaml b/dev/integration_tests/ios_platform_view_tests/pubspec.yaml
index 89cc39a..0ce093a 100644
--- a/dev/integration_tests/ios_platform_view_tests/pubspec.yaml
+++ b/dev/integration_tests/ios_platform_view_tests/pubspec.yaml
@@ -16,40 +16,42 @@
characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
collection: 1.17.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
file: 6.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
matcher: 0.12.16 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.9.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path: 1.8.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
sync_http: 0.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- vm_service: 11.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ vm_service: 11.7.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
flutter_test:
sdk: flutter
- test: 1.24.3
+ test: 1.24.4
- _fe_analyzer_shared: 61.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- analyzer: 5.13.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ _fe_analyzer_shared: 62.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ analyzer: 6.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
args: 2.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
clock: 1.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
convert: 3.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
coverage: 1.6.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
crypto: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ dart_internal: 0.2.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
fake_async: 1.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
frontend_server_client: 3.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
glob: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http_multi_server: 3.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http_parser: 4.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
io: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
logging: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
mime: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
node_preamble: 2.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -62,7 +64,7 @@
shelf_web_socket: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_map_stack_trace: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_maps: 0.10.12 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_core: 0.5.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_core: 0.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -76,4 +78,4 @@
# the material Icons class.
uses-material-design: true
-# PUBSPEC CHECKSUM: db36
+# PUBSPEC CHECKSUM: be20
diff --git a/dev/integration_tests/non_nullable/android/build.gradle b/dev/integration_tests/non_nullable/android/build.gradle
index 57ace36..a2a8866 100644
--- a/dev/integration_tests/non_nullable/android/build.gradle
+++ b/dev/integration_tests/non_nullable/android/build.gradle
@@ -7,14 +7,14 @@
// See dev/tools/bin/generate_gradle_lockfiles.dart.
buildscript {
- ext.kotlin_version = '1.5.31'
+ ext.kotlin_version = '1.7.10'
repositories {
google()
mavenCentral()
}
dependencies {
- classpath 'com.android.tools.build:gradle:4.1.3'
+ classpath 'com.android.tools.build:gradle:7.3.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
diff --git a/dev/integration_tests/non_nullable/android/buildscript-gradle.lockfile b/dev/integration_tests/non_nullable/android/buildscript-gradle.lockfile
index 2577f0a..eb60580 100644
--- a/dev/integration_tests/non_nullable/android/buildscript-gradle.lockfile
+++ b/dev/integration_tests/non_nullable/android/buildscript-gradle.lockfile
@@ -1,120 +1,152 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
-androidx.databinding:databinding-common:4.1.3=classpath
-androidx.databinding:databinding-compiler-common:4.1.3=classpath
-com.android.databinding:baseLibrary:4.1.3=classpath
-com.android.tools.analytics-library:crash:27.1.3=classpath
-com.android.tools.analytics-library:protos:27.1.3=classpath
-com.android.tools.analytics-library:shared:27.1.3=classpath
-com.android.tools.analytics-library:tracker:27.1.3=classpath
-com.android.tools.build.jetifier:jetifier-core:1.0.0-beta09=classpath
-com.android.tools.build.jetifier:jetifier-processor:1.0.0-beta09=classpath
-com.android.tools.build:aapt2-proto:4.1.3-6503028=classpath
-com.android.tools.build:aaptcompiler:4.1.3=classpath
-com.android.tools.build:apksig:4.1.3=classpath
-com.android.tools.build:apkzlib:4.1.3=classpath
-com.android.tools.build:builder-model:4.1.3=classpath
-com.android.tools.build:builder-test-api:4.1.3=classpath
-com.android.tools.build:builder:4.1.3=classpath
-com.android.tools.build:bundletool:0.14.0=classpath
-com.android.tools.build:gradle-api:4.1.3=classpath
-com.android.tools.build:gradle:4.1.3=classpath
-com.android.tools.build:manifest-merger:27.1.3=classpath
+androidx.databinding:databinding-common:7.3.0=classpath
+androidx.databinding:databinding-compiler-common:7.3.0=classpath
+com.android.databinding:baseLibrary:7.3.0=classpath
+com.android.tools.analytics-library:crash:30.3.0=classpath
+com.android.tools.analytics-library:protos:30.3.0=classpath
+com.android.tools.analytics-library:shared:30.3.0=classpath
+com.android.tools.analytics-library:tracker:30.3.0=classpath
+com.android.tools.build.jetifier:jetifier-core:1.0.0-beta10=classpath
+com.android.tools.build.jetifier:jetifier-processor:1.0.0-beta10=classpath
+com.android.tools.build:aapt2-proto:7.3.0-8691043=classpath
+com.android.tools.build:aaptcompiler:7.3.0=classpath
+com.android.tools.build:apksig:7.3.0=classpath
+com.android.tools.build:apkzlib:7.3.0=classpath
+com.android.tools.build:builder-model:7.3.0=classpath
+com.android.tools.build:builder-test-api:7.3.0=classpath
+com.android.tools.build:builder:7.3.0=classpath
+com.android.tools.build:bundletool:1.9.0=classpath
+com.android.tools.build:gradle-api:7.3.0=classpath
+com.android.tools.build:gradle:7.3.0=classpath
+com.android.tools.build:manifest-merger:30.3.0=classpath
com.android.tools.build:transform-api:2.0.0-deprecated-use-gradle-api=classpath
-com.android.tools.ddms:ddmlib:27.1.3=classpath
-com.android.tools.layoutlib:layoutlib-api:27.1.3=classpath
-com.android.tools.lint:lint-gradle-api:27.1.3=classpath
-com.android.tools.lint:lint-model:27.1.3=classpath
-com.android.tools:annotations:27.1.3=classpath
-com.android.tools:common:27.1.3=classpath
-com.android.tools:dvlib:27.1.3=classpath
-com.android.tools:repository:27.1.3=classpath
-com.android.tools:sdk-common:27.1.3=classpath
-com.android.tools:sdklib:27.1.3=classpath
-com.android:signflinger:4.1.3=classpath
-com.android:zipflinger:4.1.3=classpath
+com.android.tools.ddms:ddmlib:30.3.0=classpath
+com.android.tools.layoutlib:layoutlib-api:30.3.0=classpath
+com.android.tools.lint:lint-model:30.3.0=classpath
+com.android.tools.lint:lint-typedef-remover:30.3.0=classpath
+com.android.tools.utp:android-device-provider-ddmlib-proto:30.3.0=classpath
+com.android.tools.utp:android-device-provider-gradle-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-host-additional-test-output-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-host-coverage-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-host-retention-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-result-listener-gradle-proto:30.3.0=classpath
+com.android.tools:annotations:30.3.0=classpath
+com.android.tools:common:30.3.0=classpath
+com.android.tools:dvlib:30.3.0=classpath
+com.android.tools:repository:30.3.0=classpath
+com.android.tools:sdk-common:30.3.0=classpath
+com.android.tools:sdklib:30.3.0=classpath
+com.android:signflinger:7.3.0=classpath
+com.android:zipflinger:7.3.0=classpath
com.github.gundy:semver4j:0.16.4=classpath
+com.google.android:annotations:4.1.1.4=classpath
+com.google.api.grpc:proto-google-common-protos:2.0.1=classpath
com.google.auto.value:auto-value-annotations:1.6.2=classpath
com.google.code.findbugs:jsr305:3.0.2=classpath
-com.google.code.gson:gson:2.8.6=classpath
+com.google.code.gson:gson:2.8.9=classpath
com.google.crypto.tink:tink:1.3.0-rc2=classpath
-com.google.errorprone:error_prone_annotations:2.3.4=classpath
+com.google.dagger:dagger:2.28.3=classpath
+com.google.errorprone:error_prone_annotations:2.4.0=classpath
com.google.flatbuffers:flatbuffers-java:1.12.0=classpath
com.google.guava:failureaccess:1.0.1=classpath
-com.google.guava:guava:29.0-jre=classpath
+com.google.guava:guava:30.1-jre=classpath
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=classpath
com.google.j2objc:j2objc-annotations:1.3=classpath
com.google.jimfs:jimfs:1.1=classpath
-com.google.protobuf:protobuf-java-util:3.10.0=classpath
-com.google.protobuf:protobuf-java:3.10.0=classpath
-com.google.test.platform:core-proto:0.0.2-dev=classpath
+com.google.protobuf:protobuf-java-util:3.17.2=classpath
+com.google.protobuf:protobuf-java:3.17.2=classpath
+com.google.testing.platform:core-proto:0.0.8-alpha07=classpath
com.googlecode.json-simple:json-simple:1.1=classpath
com.googlecode.juniversalchardet:juniversalchardet:1.0.3=classpath
com.squareup:javapoet:1.10.0=classpath
com.squareup:javawriter:2.5.0=classpath
com.sun.activation:javax.activation:1.2.0=classpath
-com.sun.istack:istack-commons-runtime:3.0.7=classpath
-com.sun.xml.fastinfoset:FastInfoset:1.2.15=classpath
-commons-codec:commons-codec:1.10=classpath
+com.sun.istack:istack-commons-runtime:3.0.8=classpath
+com.sun.xml.fastinfoset:FastInfoset:1.2.16=classpath
+commons-codec:commons-codec:1.11=classpath
commons-io:commons-io:2.4=classpath
commons-logging:commons-logging:1.2=classpath
de.undercouch:gradle-download-task:4.1.1=classpath
-it.unimi.dsi:fastutil:7.2.0=classpath
-javax.activation:javax.activation-api:1.2.0=classpath
+io.grpc:grpc-api:1.39.0=classpath
+io.grpc:grpc-context:1.39.0=classpath
+io.grpc:grpc-core:1.39.0=classpath
+io.grpc:grpc-netty:1.39.0=classpath
+io.grpc:grpc-protobuf-lite:1.39.0=classpath
+io.grpc:grpc-protobuf:1.39.0=classpath
+io.grpc:grpc-stub:1.39.0=classpath
+io.netty:netty-buffer:4.1.52.Final=classpath
+io.netty:netty-codec-http2:4.1.52.Final=classpath
+io.netty:netty-codec-http:4.1.52.Final=classpath
+io.netty:netty-codec-socks:4.1.52.Final=classpath
+io.netty:netty-codec:4.1.52.Final=classpath
+io.netty:netty-common:4.1.52.Final=classpath
+io.netty:netty-handler-proxy:4.1.52.Final=classpath
+io.netty:netty-handler:4.1.52.Final=classpath
+io.netty:netty-resolver:4.1.52.Final=classpath
+io.netty:netty-transport:4.1.52.Final=classpath
+io.perfmark:perfmark-api:0.23.0=classpath
+it.unimi.dsi:fastutil:8.4.0=classpath
+jakarta.activation:jakarta.activation-api:1.2.1=classpath
+jakarta.xml.bind:jakarta.xml.bind-api:2.3.2=classpath
+javax.annotation:javax.annotation-api:1.3.2=classpath
javax.inject:javax.inject:1=classpath
-javax.xml.bind:jaxb-api:2.3.1=classpath
+net.java.dev.jna:jna-platform:5.6.0=classpath
+net.java.dev.jna:jna:5.6.0=classpath
net.sf.jopt-simple:jopt-simple:4.9=classpath
net.sf.kxml:kxml2:2.3.0=classpath
-net.sf.proguard:proguard-base:6.0.3=classpath
-net.sf.proguard:proguard-gradle:6.0.3=classpath
-org.antlr:antlr4:4.5.3=classpath
-org.apache.commons:commons-compress:1.12=classpath
-org.apache.httpcomponents:httpclient:4.5.6=classpath
-org.apache.httpcomponents:httpcore:4.4.10=classpath
+org.apache.commons:commons-compress:1.20=classpath
+org.apache.httpcomponents:httpclient:4.5.13=classpath
+org.apache.httpcomponents:httpcore:4.4.13=classpath
org.apache.httpcomponents:httpmime:4.5.6=classpath
-org.bouncycastle:bcpkix-jdk15on:1.56=classpath
-org.bouncycastle:bcprov-jdk15on:1.56=classpath
-org.checkerframework:checker-qual:2.11.1=classpath
-org.glassfish.jaxb:jaxb-runtime:2.3.1=classpath
-org.glassfish.jaxb:txw2:2.3.1=classpath
+org.bitbucket.b_c:jose4j:0.7.0=classpath
+org.bouncycastle:bcpkix-jdk15on:1.67=classpath
+org.bouncycastle:bcprov-jdk15on:1.67=classpath
+org.checkerframework:checker-qual:3.5.0=classpath
+org.codehaus.mojo:animal-sniffer-annotations:1.19=classpath
+org.glassfish.jaxb:jaxb-runtime:2.3.2=classpath
+org.glassfish.jaxb:txw2:2.3.2=classpath
org.jdom:jdom2:2.0.6=classpath
-org.jetbrains.intellij.deps:trove4j:1.0.20181211=classpath
-org.jetbrains.kotlin:kotlin-android-extensions:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-annotation-processing-gradle:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-build-common:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-compiler-embeddable:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-compiler-runner:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-daemon-client:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-daemon-embeddable:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-native-utils:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-project-model:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-reflect:1.3.72=classpath
-org.jetbrains.kotlin:kotlin-scripting-common:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-scripting-jvm:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-stdlib-common:1.3.72=classpath
-org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.72=classpath
-org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.72=classpath
-org.jetbrains.kotlin:kotlin-stdlib:1.3.72=classpath
-org.jetbrains.kotlin:kotlin-tooling-metadata:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-util-io:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-util-klib:1.5.31=classpath
+org.jetbrains.intellij.deps:trove4j:1.0.20200330=classpath
+org.jetbrains.kotlin:kotlin-android-extensions:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-annotation-processing-gradle:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-build-common:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-compiler-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-compiler-runner:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-daemon-client:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-daemon-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin-idea:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-native-utils:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-project-model:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-reflect:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-scripting-common:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-scripting-jvm:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-stdlib-common:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-stdlib:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-tooling-core:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-tooling-metadata:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-util-io:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-util-klib:1.7.10=classpath
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.0=classpath
-org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0=classpath
-org.jetbrains.trove4j:trove4j:20160824=classpath
org.jetbrains:annotations:13.0=classpath
org.json:json:20180813=classpath
-org.jvnet.staxex:stax-ex:1.8=classpath
-org.ow2.asm:asm-analysis:7.0=classpath
-org.ow2.asm:asm-commons:7.0=classpath
-org.ow2.asm:asm-tree:7.0=classpath
-org.ow2.asm:asm-util:7.0=classpath
-org.ow2.asm:asm:7.0=classpath
-org.tensorflow:tensorflow-lite-metadata:0.1.0-rc1=classpath
+org.jvnet.staxex:stax-ex:1.8.1=classpath
+org.ow2.asm:asm-analysis:9.1=classpath
+org.ow2.asm:asm-commons:9.1=classpath
+org.ow2.asm:asm-tree:9.1=classpath
+org.ow2.asm:asm-util:9.1=classpath
+org.ow2.asm:asm:9.1=classpath
+org.slf4j:slf4j-api:1.7.30=classpath
+org.tensorflow:tensorflow-lite-metadata:0.1.0-rc2=classpath
+xerces:xercesImpl:2.12.0=classpath
+xml-apis:xml-apis:1.4.01=classpath
empty=
diff --git a/dev/integration_tests/non_nullable/android/project-app.lockfile b/dev/integration_tests/non_nullable/android/project-app.lockfile
index c573760..5e0f607 100644
--- a/dev/integration_tests/non_nullable/android/project-app.lockfile
+++ b/dev/integration_tests/non_nullable/android/project-app.lockfile
@@ -21,8 +21,8 @@
androidx.tracing:tracing:1.0.0=debugAndroidTestCompileClasspath,debugApiDependenciesMetadata,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileApiDependenciesMetadata,profileCompileClasspath,profileImplementationDependenciesMetadata,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseApiDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
androidx.versionedparcelable:versionedparcelable:1.1.1=debugAndroidTestCompileClasspath,debugApiDependenciesMetadata,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileApiDependenciesMetadata,profileCompileClasspath,profileImplementationDependenciesMetadata,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseApiDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
androidx.viewpager:viewpager:1.0.0=debugAndroidTestCompileClasspath,debugApiDependenciesMetadata,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileApiDependenciesMetadata,profileCompileClasspath,profileImplementationDependenciesMetadata,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseApiDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
-androidx.window:window-java:1.0.0-beta03=debugAndroidTestCompileClasspath,debugApiDependenciesMetadata,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileApiDependenciesMetadata,profileCompileClasspath,profileImplementationDependenciesMetadata,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseApiDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
-androidx.window:window:1.0.0-beta03=debugAndroidTestCompileClasspath,debugApiDependenciesMetadata,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileApiDependenciesMetadata,profileCompileClasspath,profileImplementationDependenciesMetadata,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseApiDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.window:window-java:1.0.0-beta04=debugAndroidTestCompileClasspath,debugApiDependenciesMetadata,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileApiDependenciesMetadata,profileCompileClasspath,profileImplementationDependenciesMetadata,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseApiDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.window:window:1.0.0-beta04=debugAndroidTestCompileClasspath,debugApiDependenciesMetadata,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileApiDependenciesMetadata,profileCompileClasspath,profileImplementationDependenciesMetadata,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseApiDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
com.android.tools.analytics-library:protos:27.1.3=lintClassPath
com.android.tools.analytics-library:shared:27.1.3=lintClassPath
com.android.tools.analytics-library:tracker:27.1.3=lintClassPath
@@ -74,6 +74,7 @@
javax.activation:javax.activation-api:1.2.0=lintClassPath
javax.inject:javax.inject:1=lintClassPath
javax.xml.bind:jaxb-api:2.3.1=lintClassPath
+net.java.dev.jna:jna:5.6.0=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
net.sf.jopt-simple:jopt-simple:4.9=lintClassPath
net.sf.kxml:kxml2:2.3.0=lintClassPath
org.apache.commons:commons-compress:1.12=lintClassPath
@@ -87,22 +88,29 @@
org.codehaus.mojo:animal-sniffer-annotations:1.18=lintClassPath
org.glassfish.jaxb:jaxb-runtime:2.3.1=lintClassPath
org.glassfish.jaxb:txw2:2.3.1=lintClassPath
-org.jetbrains.intellij.deps:trove4j:1.0.20181211=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
-org.jetbrains.kotlin:kotlin-compiler-embeddable:1.5.31=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
-org.jetbrains.kotlin:kotlin-daemon-embeddable:1.5.31=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
-org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:1.5.31=kotlinKlibCommonizerClasspath
+org.jacoco:org.jacoco.agent:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.ant:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.core:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.report:0.8.7=androidJacocoAnt
+org.jetbrains.intellij.deps:trove4j:1.0.20200330=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
+org.jetbrains.kotlin:kotlin-compiler-embeddable:1.7.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
+org.jetbrains.kotlin:kotlin-daemon-embeddable:1.7.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
+org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:1.7.10=kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-reflect:1.3.72=lintClassPath
-org.jetbrains.kotlin:kotlin-reflect:1.5.31=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
-org.jetbrains.kotlin:kotlin-script-runtime:1.5.31=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
+org.jetbrains.kotlin:kotlin-reflect:1.7.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
+org.jetbrains.kotlin:kotlin-script-runtime:1.7.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-stdlib-common:1.3.72=lintClassPath
-org.jetbrains.kotlin:kotlin-stdlib-common:1.5.31=debugAndroidTestCompileClasspath,debugApiDependenciesMetadata,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,profileApiDependenciesMetadata,profileCompileClasspath,profileImplementationDependenciesMetadata,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseApiDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlin:kotlin-stdlib-common:1.5.31=debugApiDependenciesMetadata,profileApiDependenciesMetadata,releaseApiDependenciesMetadata
+org.jetbrains.kotlin:kotlin-stdlib-common:1.7.10=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,profileCompileClasspath,profileImplementationDependenciesMetadata,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.72=lintClassPath
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.5.30=debugApiDependenciesMetadata,profileApiDependenciesMetadata,releaseApiDependenciesMetadata
-org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.5.31=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,profileCompileClasspath,profileImplementationDependenciesMetadata,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.10=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,profileCompileClasspath,profileImplementationDependenciesMetadata,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.72=lintClassPath
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.30=debugAndroidTestCompileClasspath,debugApiDependenciesMetadata,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileApiDependenciesMetadata,profileCompileClasspath,profileImplementationDependenciesMetadata,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseApiDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.jetbrains.kotlin:kotlin-stdlib:1.3.72=lintClassPath
-org.jetbrains.kotlin:kotlin-stdlib:1.5.31=debugAndroidTestCompileClasspath,debugApiDependenciesMetadata,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,profileApiDependenciesMetadata,profileCompileClasspath,profileImplementationDependenciesMetadata,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseApiDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlin:kotlin-stdlib:1.5.31=debugApiDependenciesMetadata,profileApiDependenciesMetadata,releaseApiDependenciesMetadata
+org.jetbrains.kotlin:kotlin-stdlib:1.7.10=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,profileCompileClasspath,profileImplementationDependenciesMetadata,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlinx:atomicfu:0.16.3=debugApiDependenciesMetadata,debugImplementationDependenciesMetadata,profileApiDependenciesMetadata,profileImplementationDependenciesMetadata,releaseApiDependenciesMetadata,releaseImplementationDependenciesMetadata
org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2=debugAndroidTestCompileClasspath,debugApiDependenciesMetadata,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileApiDependenciesMetadata,profileCompileClasspath,profileImplementationDependenciesMetadata,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseApiDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.2=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2=debugAndroidTestCompileClasspath,debugApiDependenciesMetadata,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileApiDependenciesMetadata,profileCompileClasspath,profileImplementationDependenciesMetadata,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseApiDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
@@ -110,8 +118,12 @@
org.jetbrains:annotations:13.0=debugAndroidTestCompileClasspath,debugApiDependenciesMetadata,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,lintClassPath,profileApiDependenciesMetadata,profileCompileClasspath,profileImplementationDependenciesMetadata,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseApiDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.jvnet.staxex:stax-ex:1.8=lintClassPath
org.ow2.asm:asm-analysis:7.0=lintClassPath
+org.ow2.asm:asm-analysis:9.1=androidJacocoAnt
org.ow2.asm:asm-commons:7.0=lintClassPath
+org.ow2.asm:asm-commons:9.1=androidJacocoAnt
org.ow2.asm:asm-tree:7.0=lintClassPath
+org.ow2.asm:asm-tree:9.1=androidJacocoAnt
org.ow2.asm:asm-util:7.0=lintClassPath
org.ow2.asm:asm:7.0=lintClassPath
-empty=androidApis,androidTestApiDependenciesMetadata,androidTestCompileOnlyDependenciesMetadata,androidTestDebugApiDependenciesMetadata,androidTestDebugCompileOnlyDependenciesMetadata,androidTestDebugImplementationDependenciesMetadata,androidTestDebugIntransitiveDependenciesMetadata,androidTestDebugRuntimeOnlyDependenciesMetadata,androidTestImplementationDependenciesMetadata,androidTestIntransitiveDependenciesMetadata,androidTestProfileApiDependenciesMetadata,androidTestProfileCompileOnlyDependenciesMetadata,androidTestProfileImplementationDependenciesMetadata,androidTestProfileIntransitiveDependenciesMetadata,androidTestProfileRuntimeOnlyDependenciesMetadata,androidTestReleaseApiDependenciesMetadata,androidTestReleaseCompileOnlyDependenciesMetadata,androidTestReleaseImplementationDependenciesMetadata,androidTestReleaseIntransitiveDependenciesMetadata,androidTestReleaseRuntimeOnlyDependenciesMetadata,androidTestRuntimeOnlyDependenciesMetadata,androidTestUtil,apiDependenciesMetadata,compile,compileOnlyDependenciesMetadata,coreLibraryDesugaring,debugAndroidTestAnnotationProcessorClasspath,debugAndroidTestApiDependenciesMetadata,debugAndroidTestCompileOnlyDependenciesMetadata,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestIntransitiveDependenciesMetadata,debugAndroidTestRuntimeClasspath,debugAndroidTestRuntimeOnlyDependenciesMetadata,debugAnnotationProcessorClasspath,debugCompile,debugCompileOnly,debugCompileOnlyDependenciesMetadata,debugIntransitiveDependenciesMetadata,debugReverseMetadataValues,debugRuntimeOnlyDependenciesMetadata,debugUnitTestAnnotationProcessorClasspath,debugUnitTestApiDependenciesMetadata,debugUnitTestCompileOnlyDependenciesMetadata,debugUnitTestImplementationDependenciesMetadata,debugUnitTestIntransitiveDependenciesMetadata,debugUnitTestRuntimeOnlyDependenciesMetadata,debugWearBundling,intransitiveDependenciesMetadata,kotlinCompilerPluginClasspath,kotlinCompilerPluginClasspathDebug,kotlinCompilerPluginClasspathDebugAndroidTest,kotlinCompilerPluginClasspathDebugUnitTest,kotlinCompilerPluginClasspathProfile,kotlinCompilerPluginClasspathProfileUnitTest,kotlinCompilerPluginClasspathRelease,kotlinCompilerPluginClasspathReleaseUnitTest,kotlinNativeCompilerPluginClasspath,lintChecks,lintPublish,profileAnnotationProcessorClasspath,profileCompile,profileCompileOnly,profileCompileOnlyDependenciesMetadata,profileIntransitiveDependenciesMetadata,profileReverseMetadataValues,profileRuntimeOnlyDependenciesMetadata,profileUnitTestAnnotationProcessorClasspath,profileUnitTestApiDependenciesMetadata,profileUnitTestCompileOnlyDependenciesMetadata,profileUnitTestImplementationDependenciesMetadata,profileUnitTestIntransitiveDependenciesMetadata,profileUnitTestRuntimeOnlyDependenciesMetadata,profileWearBundling,releaseAnnotationProcessorClasspath,releaseCompile,releaseCompileOnly,releaseCompileOnlyDependenciesMetadata,releaseIntransitiveDependenciesMetadata,releaseReverseMetadataValues,releaseRuntimeOnlyDependenciesMetadata,releaseUnitTestAnnotationProcessorClasspath,releaseUnitTestApiDependenciesMetadata,releaseUnitTestCompileOnlyDependenciesMetadata,releaseUnitTestImplementationDependenciesMetadata,releaseUnitTestIntransitiveDependenciesMetadata,releaseUnitTestRuntimeOnlyDependenciesMetadata,releaseWearBundling,runtimeOnlyDependenciesMetadata,testApiDependenciesMetadata,testCompile,testCompileOnlyDependenciesMetadata,testDebugApiDependenciesMetadata,testDebugCompileOnlyDependenciesMetadata,testDebugImplementationDependenciesMetadata,testDebugIntransitiveDependenciesMetadata,testDebugRuntimeOnlyDependenciesMetadata,testImplementationDependenciesMetadata,testIntransitiveDependenciesMetadata,testProfileApiDependenciesMetadata,testProfileCompileOnlyDependenciesMetadata,testProfileImplementationDependenciesMetadata,testProfileIntransitiveDependenciesMetadata,testProfileRuntimeOnlyDependenciesMetadata,testReleaseApiDependenciesMetadata,testReleaseCompileOnlyDependenciesMetadata,testReleaseImplementationDependenciesMetadata,testReleaseIntransitiveDependenciesMetadata,testReleaseRuntimeOnlyDependenciesMetadata,testRuntimeOnlyDependenciesMetadata
+org.ow2.asm:asm:9.1=androidJacocoAnt
+empty=androidApis,androidJdkImage,androidTestApiDependenciesMetadata,androidTestCompileOnlyDependenciesMetadata,androidTestDebugApiDependenciesMetadata,androidTestDebugCompileOnlyDependenciesMetadata,androidTestDebugImplementationDependenciesMetadata,androidTestDebugIntransitiveDependenciesMetadata,androidTestDebugRuntimeOnlyDependenciesMetadata,androidTestImplementationDependenciesMetadata,androidTestIntransitiveDependenciesMetadata,androidTestProfileApiDependenciesMetadata,androidTestProfileCompileOnlyDependenciesMetadata,androidTestProfileImplementationDependenciesMetadata,androidTestProfileIntransitiveDependenciesMetadata,androidTestProfileRuntimeOnlyDependenciesMetadata,androidTestReleaseApiDependenciesMetadata,androidTestReleaseCompileOnlyDependenciesMetadata,androidTestReleaseImplementationDependenciesMetadata,androidTestReleaseIntransitiveDependenciesMetadata,androidTestReleaseRuntimeOnlyDependenciesMetadata,androidTestRuntimeOnlyDependenciesMetadata,androidTestUtil,apiDependenciesMetadata,compile,compileOnlyDependenciesMetadata,coreLibraryDesugaring,debugAndroidTestAnnotationProcessorClasspath,debugAndroidTestApiDependenciesMetadata,debugAndroidTestCompileOnlyDependenciesMetadata,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestIntransitiveDependenciesMetadata,debugAndroidTestRuntimeClasspath,debugAndroidTestRuntimeOnlyDependenciesMetadata,debugAnnotationProcessorClasspath,debugCompile,debugCompileOnly,debugCompileOnlyDependenciesMetadata,debugIntransitiveDependenciesMetadata,debugReverseMetadataValues,debugRuntimeOnlyDependenciesMetadata,debugUnitTestAnnotationProcessorClasspath,debugUnitTestApiDependenciesMetadata,debugUnitTestCompileOnlyDependenciesMetadata,debugUnitTestImplementationDependenciesMetadata,debugUnitTestIntransitiveDependenciesMetadata,debugUnitTestRuntimeOnlyDependenciesMetadata,debugWearBundling,intransitiveDependenciesMetadata,kotlinCompilerPluginClasspath,kotlinCompilerPluginClasspathDebug,kotlinCompilerPluginClasspathDebugAndroidTest,kotlinCompilerPluginClasspathDebugUnitTest,kotlinCompilerPluginClasspathProfile,kotlinCompilerPluginClasspathProfileUnitTest,kotlinCompilerPluginClasspathRelease,kotlinCompilerPluginClasspathReleaseUnitTest,kotlinNativeCompilerPluginClasspath,lintChecks,lintPublish,profileAnnotationProcessorClasspath,profileCompile,profileCompileOnly,profileCompileOnlyDependenciesMetadata,profileIntransitiveDependenciesMetadata,profileReverseMetadataValues,profileRuntimeOnlyDependenciesMetadata,profileUnitTestAnnotationProcessorClasspath,profileUnitTestApiDependenciesMetadata,profileUnitTestCompileOnlyDependenciesMetadata,profileUnitTestImplementationDependenciesMetadata,profileUnitTestIntransitiveDependenciesMetadata,profileUnitTestRuntimeOnlyDependenciesMetadata,profileWearBundling,releaseAnnotationProcessorClasspath,releaseCompile,releaseCompileOnly,releaseCompileOnlyDependenciesMetadata,releaseIntransitiveDependenciesMetadata,releaseReverseMetadataValues,releaseRuntimeOnlyDependenciesMetadata,releaseUnitTestAnnotationProcessorClasspath,releaseUnitTestApiDependenciesMetadata,releaseUnitTestCompileOnlyDependenciesMetadata,releaseUnitTestImplementationDependenciesMetadata,releaseUnitTestIntransitiveDependenciesMetadata,releaseUnitTestRuntimeOnlyDependenciesMetadata,releaseWearBundling,runtimeOnlyDependenciesMetadata,testApiDependenciesMetadata,testCompile,testCompileOnlyDependenciesMetadata,testDebugApiDependenciesMetadata,testDebugCompileOnlyDependenciesMetadata,testDebugImplementationDependenciesMetadata,testDebugIntransitiveDependenciesMetadata,testDebugRuntimeOnlyDependenciesMetadata,testFixturesApiDependenciesMetadata,testFixturesCompileOnlyDependenciesMetadata,testFixturesDebugApiDependenciesMetadata,testFixturesDebugCompileOnlyDependenciesMetadata,testFixturesDebugImplementationDependenciesMetadata,testFixturesDebugIntransitiveDependenciesMetadata,testFixturesDebugRuntimeOnlyDependenciesMetadata,testFixturesImplementationDependenciesMetadata,testFixturesIntransitiveDependenciesMetadata,testFixturesProfileApiDependenciesMetadata,testFixturesProfileCompileOnlyDependenciesMetadata,testFixturesProfileImplementationDependenciesMetadata,testFixturesProfileIntransitiveDependenciesMetadata,testFixturesProfileRuntimeOnlyDependenciesMetadata,testFixturesReleaseApiDependenciesMetadata,testFixturesReleaseCompileOnlyDependenciesMetadata,testFixturesReleaseImplementationDependenciesMetadata,testFixturesReleaseIntransitiveDependenciesMetadata,testFixturesReleaseRuntimeOnlyDependenciesMetadata,testFixturesRuntimeOnlyDependenciesMetadata,testImplementationDependenciesMetadata,testIntransitiveDependenciesMetadata,testProfileApiDependenciesMetadata,testProfileCompileOnlyDependenciesMetadata,testProfileImplementationDependenciesMetadata,testProfileIntransitiveDependenciesMetadata,testProfileRuntimeOnlyDependenciesMetadata,testReleaseApiDependenciesMetadata,testReleaseCompileOnlyDependenciesMetadata,testReleaseImplementationDependenciesMetadata,testReleaseIntransitiveDependenciesMetadata,testReleaseRuntimeOnlyDependenciesMetadata,testRuntimeOnlyDependenciesMetadata
diff --git a/dev/integration_tests/non_nullable/android/settings.gradle b/dev/integration_tests/non_nullable/android/settings.gradle
index 03ae72d..a020595 100644
--- a/dev/integration_tests/non_nullable/android/settings.gradle
+++ b/dev/integration_tests/non_nullable/android/settings.gradle
@@ -8,8 +8,6 @@
include ':app'
-enableFeaturePreview('ONE_LOCKFILE_PER_PROJECT')
-
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()
diff --git a/dev/integration_tests/non_nullable/ios/Runner/Info.plist b/dev/integration_tests/non_nullable/ios/Runner/Info.plist
index 132b9d5..bbe2edc 100644
--- a/dev/integration_tests/non_nullable/ios/Runner/Info.plist
+++ b/dev/integration_tests/non_nullable/ios/Runner/Info.plist
@@ -39,8 +39,6 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
- <key>UIViewControllerBasedStatusBarAppearance</key>
- <false/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
diff --git a/dev/integration_tests/non_nullable/pubspec.yaml b/dev/integration_tests/non_nullable/pubspec.yaml
index ff5e5b5..16142b2 100644
--- a/dev/integration_tests/non_nullable/pubspec.yaml
+++ b/dev/integration_tests/non_nullable/pubspec.yaml
@@ -14,10 +14,10 @@
characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
collection: 1.17.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.9.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
flutter_test:
@@ -30,13 +30,13 @@
matcher: 0.12.16 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path: 1.8.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
flutter:
uses-material-design: true
-# PUBSPEC CHECKSUM: 3dc5
+# PUBSPEC CHECKSUM: beec
diff --git a/dev/integration_tests/platform_interaction/android/build.gradle b/dev/integration_tests/platform_interaction/android/build.gradle
index d3c7bfb..a2a8866 100644
--- a/dev/integration_tests/platform_interaction/android/build.gradle
+++ b/dev/integration_tests/platform_interaction/android/build.gradle
@@ -7,14 +7,14 @@
// See dev/tools/bin/generate_gradle_lockfiles.dart.
buildscript {
- ext.kotlin_version = '1.6.21'
+ ext.kotlin_version = '1.7.10'
repositories {
google()
mavenCentral()
}
dependencies {
- classpath 'com.android.tools.build:gradle:7.4.2'
+ classpath 'com.android.tools.build:gradle:7.3.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
diff --git a/dev/integration_tests/platform_interaction/android/buildscript-gradle.lockfile b/dev/integration_tests/platform_interaction/android/buildscript-gradle.lockfile
index 814eb13..eb60580 100644
--- a/dev/integration_tests/platform_interaction/android/buildscript-gradle.lockfile
+++ b/dev/integration_tests/platform_interaction/android/buildscript-gradle.lockfile
@@ -1,46 +1,45 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
-androidx.databinding:databinding-common:7.4.2=classpath
-androidx.databinding:databinding-compiler-common:7.4.2=classpath
-com.android.databinding:baseLibrary:7.4.2=classpath
-com.android.tools.analytics-library:crash:30.4.2=classpath
-com.android.tools.analytics-library:protos:30.4.2=classpath
-com.android.tools.analytics-library:shared:30.4.2=classpath
-com.android.tools.analytics-library:tracker:30.4.2=classpath
+androidx.databinding:databinding-common:7.3.0=classpath
+androidx.databinding:databinding-compiler-common:7.3.0=classpath
+com.android.databinding:baseLibrary:7.3.0=classpath
+com.android.tools.analytics-library:crash:30.3.0=classpath
+com.android.tools.analytics-library:protos:30.3.0=classpath
+com.android.tools.analytics-library:shared:30.3.0=classpath
+com.android.tools.analytics-library:tracker:30.3.0=classpath
com.android.tools.build.jetifier:jetifier-core:1.0.0-beta10=classpath
com.android.tools.build.jetifier:jetifier-processor:1.0.0-beta10=classpath
-com.android.tools.build:aapt2-proto:7.4.2-8841542=classpath
-com.android.tools.build:aaptcompiler:7.4.2=classpath
-com.android.tools.build:apksig:7.4.2=classpath
-com.android.tools.build:apkzlib:7.4.2=classpath
-com.android.tools.build:builder-model:7.4.2=classpath
-com.android.tools.build:builder-test-api:7.4.2=classpath
-com.android.tools.build:builder:7.4.2=classpath
-com.android.tools.build:bundletool:1.11.4=classpath
-com.android.tools.build:gradle-api:7.4.2=classpath
-com.android.tools.build:gradle-settings-api:7.4.2=classpath
-com.android.tools.build:gradle:7.4.2=classpath
-com.android.tools.build:manifest-merger:30.4.2=classpath
+com.android.tools.build:aapt2-proto:7.3.0-8691043=classpath
+com.android.tools.build:aaptcompiler:7.3.0=classpath
+com.android.tools.build:apksig:7.3.0=classpath
+com.android.tools.build:apkzlib:7.3.0=classpath
+com.android.tools.build:builder-model:7.3.0=classpath
+com.android.tools.build:builder-test-api:7.3.0=classpath
+com.android.tools.build:builder:7.3.0=classpath
+com.android.tools.build:bundletool:1.9.0=classpath
+com.android.tools.build:gradle-api:7.3.0=classpath
+com.android.tools.build:gradle:7.3.0=classpath
+com.android.tools.build:manifest-merger:30.3.0=classpath
com.android.tools.build:transform-api:2.0.0-deprecated-use-gradle-api=classpath
-com.android.tools.ddms:ddmlib:30.4.2=classpath
-com.android.tools.layoutlib:layoutlib-api:30.4.2=classpath
-com.android.tools.lint:lint-model:30.4.2=classpath
-com.android.tools.lint:lint-typedef-remover:30.4.2=classpath
-com.android.tools.utp:android-device-provider-ddmlib-proto:30.4.2=classpath
-com.android.tools.utp:android-device-provider-gradle-proto:30.4.2=classpath
-com.android.tools.utp:android-test-plugin-host-additional-test-output-proto:30.4.2=classpath
-com.android.tools.utp:android-test-plugin-host-coverage-proto:30.4.2=classpath
-com.android.tools.utp:android-test-plugin-host-retention-proto:30.4.2=classpath
-com.android.tools.utp:android-test-plugin-result-listener-gradle-proto:30.4.2=classpath
-com.android.tools:annotations:30.4.2=classpath
-com.android.tools:common:30.4.2=classpath
-com.android.tools:dvlib:30.4.2=classpath
-com.android.tools:repository:30.4.2=classpath
-com.android.tools:sdk-common:30.4.2=classpath
-com.android.tools:sdklib:30.4.2=classpath
-com.android:signflinger:7.4.2=classpath
-com.android:zipflinger:7.4.2=classpath
+com.android.tools.ddms:ddmlib:30.3.0=classpath
+com.android.tools.layoutlib:layoutlib-api:30.3.0=classpath
+com.android.tools.lint:lint-model:30.3.0=classpath
+com.android.tools.lint:lint-typedef-remover:30.3.0=classpath
+com.android.tools.utp:android-device-provider-ddmlib-proto:30.3.0=classpath
+com.android.tools.utp:android-device-provider-gradle-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-host-additional-test-output-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-host-coverage-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-host-retention-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-result-listener-gradle-proto:30.3.0=classpath
+com.android.tools:annotations:30.3.0=classpath
+com.android.tools:common:30.3.0=classpath
+com.android.tools:dvlib:30.3.0=classpath
+com.android.tools:repository:30.3.0=classpath
+com.android.tools:sdk-common:30.3.0=classpath
+com.android.tools:sdklib:30.3.0=classpath
+com.android:signflinger:7.3.0=classpath
+com.android:zipflinger:7.3.0=classpath
com.github.gundy:semver4j:0.16.4=classpath
com.google.android:annotations:4.1.1.4=classpath
com.google.api.grpc:proto-google-common-protos:2.0.1=classpath
@@ -58,7 +57,8 @@
com.google.jimfs:jimfs:1.1=classpath
com.google.protobuf:protobuf-java-util:3.17.2=classpath
com.google.protobuf:protobuf-java:3.17.2=classpath
-com.google.testing.platform:core-proto:0.0.8-alpha08=classpath
+com.google.testing.platform:core-proto:0.0.8-alpha07=classpath
+com.googlecode.json-simple:json-simple:1.1=classpath
com.googlecode.juniversalchardet:juniversalchardet:1.0.3=classpath
com.squareup:javapoet:1.10.0=classpath
com.squareup:javawriter:2.5.0=classpath
@@ -87,6 +87,7 @@
io.netty:netty-resolver:4.1.52.Final=classpath
io.netty:netty-transport:4.1.52.Final=classpath
io.perfmark:perfmark-api:0.23.0=classpath
+it.unimi.dsi:fastutil:8.4.0=classpath
jakarta.activation:jakarta.activation-api:1.2.1=classpath
jakarta.xml.bind:jakarta.xml.bind-api:2.3.2=classpath
javax.annotation:javax.annotation-api:1.3.2=classpath
@@ -108,40 +109,42 @@
org.glassfish.jaxb:txw2:2.3.2=classpath
org.jdom:jdom2:2.0.6=classpath
org.jetbrains.intellij.deps:trove4j:1.0.20200330=classpath
-org.jetbrains.kotlin:kotlin-android-extensions:1.6.21=classpath
-org.jetbrains.kotlin:kotlin-annotation-processing-gradle:1.6.21=classpath
-org.jetbrains.kotlin:kotlin-build-common:1.6.21=classpath
-org.jetbrains.kotlin:kotlin-compiler-embeddable:1.6.21=classpath
-org.jetbrains.kotlin:kotlin-compiler-runner:1.6.21=classpath
-org.jetbrains.kotlin:kotlin-daemon-client:1.6.21=classpath
-org.jetbrains.kotlin:kotlin-daemon-embeddable:1.6.21=classpath
-org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.6.21=classpath
-org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.6.21=classpath
-org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.21=classpath
-org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.6.21=classpath
-org.jetbrains.kotlin:kotlin-native-utils:1.6.21=classpath
-org.jetbrains.kotlin:kotlin-project-model:1.6.21=classpath
-org.jetbrains.kotlin:kotlin-reflect:1.7.10=classpath
-org.jetbrains.kotlin:kotlin-scripting-common:1.6.21=classpath
-org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.6.21=classpath
-org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.6.21=classpath
-org.jetbrains.kotlin:kotlin-scripting-jvm:1.6.21=classpath
-org.jetbrains.kotlin:kotlin-stdlib-common:1.7.10=classpath
-org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.10=classpath
-org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.10=classpath
-org.jetbrains.kotlin:kotlin-stdlib:1.7.10=classpath
-org.jetbrains.kotlin:kotlin-tooling-metadata:1.6.21=classpath
-org.jetbrains.kotlin:kotlin-util-io:1.6.21=classpath
-org.jetbrains.kotlin:kotlin-util-klib:1.6.21=classpath
+org.jetbrains.kotlin:kotlin-android-extensions:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-annotation-processing-gradle:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-build-common:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-compiler-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-compiler-runner:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-daemon-client:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-daemon-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin-idea:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-native-utils:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-project-model:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-reflect:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-scripting-common:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-scripting-jvm:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-stdlib-common:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-stdlib:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-tooling-core:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-tooling-metadata:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-util-io:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-util-klib:1.7.10=classpath
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.0=classpath
org.jetbrains:annotations:13.0=classpath
org.json:json:20180813=classpath
org.jvnet.staxex:stax-ex:1.8.1=classpath
-org.ow2.asm:asm-analysis:9.2=classpath
-org.ow2.asm:asm-commons:9.2=classpath
-org.ow2.asm:asm-tree:9.2=classpath
-org.ow2.asm:asm-util:9.2=classpath
-org.ow2.asm:asm:9.2=classpath
+org.ow2.asm:asm-analysis:9.1=classpath
+org.ow2.asm:asm-commons:9.1=classpath
+org.ow2.asm:asm-tree:9.1=classpath
+org.ow2.asm:asm-util:9.1=classpath
+org.ow2.asm:asm:9.1=classpath
org.slf4j:slf4j-api:1.7.30=classpath
org.tensorflow:tensorflow-lite-metadata:0.1.0-rc2=classpath
xerces:xercesImpl:2.12.0=classpath
diff --git a/dev/integration_tests/platform_interaction/android/project-app.lockfile b/dev/integration_tests/platform_interaction/android/project-app.lockfile
index 0d87887..e160a81 100644
--- a/dev/integration_tests/platform_interaction/android/project-app.lockfile
+++ b/dev/integration_tests/platform_interaction/android/project-app.lockfile
@@ -87,10 +87,10 @@
org.codehaus.mojo:animal-sniffer-annotations:1.18=lintClassPath
org.glassfish.jaxb:jaxb-runtime:2.3.1=lintClassPath
org.glassfish.jaxb:txw2:2.3.1=lintClassPath
-org.jacoco:org.jacoco.agent:0.8.8=androidJacocoAnt
-org.jacoco:org.jacoco.ant:0.8.8=androidJacocoAnt
-org.jacoco:org.jacoco.core:0.8.8=androidJacocoAnt
-org.jacoco:org.jacoco.report:0.8.8=androidJacocoAnt
+org.jacoco:org.jacoco.agent:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.ant:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.core:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.report:0.8.7=androidJacocoAnt
org.jetbrains.kotlin:kotlin-reflect:1.3.72=lintClassPath
org.jetbrains.kotlin:kotlin-stdlib-common:1.3.72=lintClassPath
org.jetbrains.kotlin:kotlin-stdlib-common:1.5.31=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
@@ -107,12 +107,12 @@
org.jetbrains:annotations:13.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,lintClassPath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.jvnet.staxex:stax-ex:1.8=lintClassPath
org.ow2.asm:asm-analysis:7.0=lintClassPath
-org.ow2.asm:asm-analysis:9.2=androidJacocoAnt
+org.ow2.asm:asm-analysis:9.1=androidJacocoAnt
org.ow2.asm:asm-commons:7.0=lintClassPath
-org.ow2.asm:asm-commons:9.2=androidJacocoAnt
+org.ow2.asm:asm-commons:9.1=androidJacocoAnt
org.ow2.asm:asm-tree:7.0=lintClassPath
-org.ow2.asm:asm-tree:9.2=androidJacocoAnt
+org.ow2.asm:asm-tree:9.1=androidJacocoAnt
org.ow2.asm:asm-util:7.0=lintClassPath
org.ow2.asm:asm:7.0=lintClassPath
-org.ow2.asm:asm:9.2=androidJacocoAnt
+org.ow2.asm:asm:9.1=androidJacocoAnt
empty=androidApis,androidJdkImage,androidTestUtil,compile,coreLibraryDesugaring,debugAndroidTestAnnotationProcessorClasspath,debugAndroidTestRuntimeClasspath,debugAnnotationProcessorClasspath,debugReverseMetadataValues,debugUnitTestAnnotationProcessorClasspath,debugWearBundling,lintChecks,lintPublish,profileAnnotationProcessorClasspath,profileReverseMetadataValues,profileUnitTestAnnotationProcessorClasspath,profileWearBundling,releaseAnnotationProcessorClasspath,releaseReverseMetadataValues,releaseUnitTestAnnotationProcessorClasspath,releaseWearBundling,testCompile
diff --git a/dev/integration_tests/platform_interaction/android/settings.gradle b/dev/integration_tests/platform_interaction/android/settings.gradle
index 03ae72d..a020595 100644
--- a/dev/integration_tests/platform_interaction/android/settings.gradle
+++ b/dev/integration_tests/platform_interaction/android/settings.gradle
@@ -8,8 +8,6 @@
include ':app'
-enableFeaturePreview('ONE_LOCKFILE_PER_PROJECT')
-
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()
diff --git a/dev/integration_tests/platform_interaction/ios/Runner/Info.plist b/dev/integration_tests/platform_interaction/ios/Runner/Info.plist
index 35bbdde..f979810 100644
--- a/dev/integration_tests/platform_interaction/ios/Runner/Info.plist
+++ b/dev/integration_tests/platform_interaction/ios/Runner/Info.plist
@@ -39,8 +39,6 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
- <key>UIViewControllerBasedStatusBarAppearance</key>
- <false/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
diff --git a/dev/integration_tests/platform_interaction/pubspec.yaml b/dev/integration_tests/platform_interaction/pubspec.yaml
index e1de618..49b4710 100644
--- a/dev/integration_tests/platform_interaction/pubspec.yaml
+++ b/dev/integration_tests/platform_interaction/pubspec.yaml
@@ -9,10 +9,10 @@
sdk: flutter
flutter_driver:
sdk: flutter
- test: 1.24.3
+ test: 1.24.4
- _fe_analyzer_shared: 61.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- analyzer: 5.13.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ _fe_analyzer_shared: 62.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ analyzer: 6.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
args: 2.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
async: 2.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -21,6 +21,7 @@
convert: 3.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
coverage: 1.6.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
crypto: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ dart_internal: 0.2.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
file: 6.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
frontend_server_client: 3.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
glob: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -45,17 +46,18 @@
source_map_stack_trace: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_maps: 0.10.12 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
sync_http: 0.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_core: 0.5.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_core: 0.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- vm_service: 11.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ vm_service: 11.7.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -64,4 +66,4 @@
flutter:
uses-material-design: true
-# PUBSPEC CHECKSUM: a079
+# PUBSPEC CHECKSUM: c363
diff --git a/dev/integration_tests/release_smoke_test/android/build.gradle b/dev/integration_tests/release_smoke_test/android/build.gradle
index 57ace36..a2a8866 100644
--- a/dev/integration_tests/release_smoke_test/android/build.gradle
+++ b/dev/integration_tests/release_smoke_test/android/build.gradle
@@ -7,14 +7,14 @@
// See dev/tools/bin/generate_gradle_lockfiles.dart.
buildscript {
- ext.kotlin_version = '1.5.31'
+ ext.kotlin_version = '1.7.10'
repositories {
google()
mavenCentral()
}
dependencies {
- classpath 'com.android.tools.build:gradle:4.1.3'
+ classpath 'com.android.tools.build:gradle:7.3.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
diff --git a/dev/integration_tests/release_smoke_test/android/buildscript-gradle.lockfile b/dev/integration_tests/release_smoke_test/android/buildscript-gradle.lockfile
index 2577f0a..eb60580 100644
--- a/dev/integration_tests/release_smoke_test/android/buildscript-gradle.lockfile
+++ b/dev/integration_tests/release_smoke_test/android/buildscript-gradle.lockfile
@@ -1,120 +1,152 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
-androidx.databinding:databinding-common:4.1.3=classpath
-androidx.databinding:databinding-compiler-common:4.1.3=classpath
-com.android.databinding:baseLibrary:4.1.3=classpath
-com.android.tools.analytics-library:crash:27.1.3=classpath
-com.android.tools.analytics-library:protos:27.1.3=classpath
-com.android.tools.analytics-library:shared:27.1.3=classpath
-com.android.tools.analytics-library:tracker:27.1.3=classpath
-com.android.tools.build.jetifier:jetifier-core:1.0.0-beta09=classpath
-com.android.tools.build.jetifier:jetifier-processor:1.0.0-beta09=classpath
-com.android.tools.build:aapt2-proto:4.1.3-6503028=classpath
-com.android.tools.build:aaptcompiler:4.1.3=classpath
-com.android.tools.build:apksig:4.1.3=classpath
-com.android.tools.build:apkzlib:4.1.3=classpath
-com.android.tools.build:builder-model:4.1.3=classpath
-com.android.tools.build:builder-test-api:4.1.3=classpath
-com.android.tools.build:builder:4.1.3=classpath
-com.android.tools.build:bundletool:0.14.0=classpath
-com.android.tools.build:gradle-api:4.1.3=classpath
-com.android.tools.build:gradle:4.1.3=classpath
-com.android.tools.build:manifest-merger:27.1.3=classpath
+androidx.databinding:databinding-common:7.3.0=classpath
+androidx.databinding:databinding-compiler-common:7.3.0=classpath
+com.android.databinding:baseLibrary:7.3.0=classpath
+com.android.tools.analytics-library:crash:30.3.0=classpath
+com.android.tools.analytics-library:protos:30.3.0=classpath
+com.android.tools.analytics-library:shared:30.3.0=classpath
+com.android.tools.analytics-library:tracker:30.3.0=classpath
+com.android.tools.build.jetifier:jetifier-core:1.0.0-beta10=classpath
+com.android.tools.build.jetifier:jetifier-processor:1.0.0-beta10=classpath
+com.android.tools.build:aapt2-proto:7.3.0-8691043=classpath
+com.android.tools.build:aaptcompiler:7.3.0=classpath
+com.android.tools.build:apksig:7.3.0=classpath
+com.android.tools.build:apkzlib:7.3.0=classpath
+com.android.tools.build:builder-model:7.3.0=classpath
+com.android.tools.build:builder-test-api:7.3.0=classpath
+com.android.tools.build:builder:7.3.0=classpath
+com.android.tools.build:bundletool:1.9.0=classpath
+com.android.tools.build:gradle-api:7.3.0=classpath
+com.android.tools.build:gradle:7.3.0=classpath
+com.android.tools.build:manifest-merger:30.3.0=classpath
com.android.tools.build:transform-api:2.0.0-deprecated-use-gradle-api=classpath
-com.android.tools.ddms:ddmlib:27.1.3=classpath
-com.android.tools.layoutlib:layoutlib-api:27.1.3=classpath
-com.android.tools.lint:lint-gradle-api:27.1.3=classpath
-com.android.tools.lint:lint-model:27.1.3=classpath
-com.android.tools:annotations:27.1.3=classpath
-com.android.tools:common:27.1.3=classpath
-com.android.tools:dvlib:27.1.3=classpath
-com.android.tools:repository:27.1.3=classpath
-com.android.tools:sdk-common:27.1.3=classpath
-com.android.tools:sdklib:27.1.3=classpath
-com.android:signflinger:4.1.3=classpath
-com.android:zipflinger:4.1.3=classpath
+com.android.tools.ddms:ddmlib:30.3.0=classpath
+com.android.tools.layoutlib:layoutlib-api:30.3.0=classpath
+com.android.tools.lint:lint-model:30.3.0=classpath
+com.android.tools.lint:lint-typedef-remover:30.3.0=classpath
+com.android.tools.utp:android-device-provider-ddmlib-proto:30.3.0=classpath
+com.android.tools.utp:android-device-provider-gradle-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-host-additional-test-output-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-host-coverage-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-host-retention-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-result-listener-gradle-proto:30.3.0=classpath
+com.android.tools:annotations:30.3.0=classpath
+com.android.tools:common:30.3.0=classpath
+com.android.tools:dvlib:30.3.0=classpath
+com.android.tools:repository:30.3.0=classpath
+com.android.tools:sdk-common:30.3.0=classpath
+com.android.tools:sdklib:30.3.0=classpath
+com.android:signflinger:7.3.0=classpath
+com.android:zipflinger:7.3.0=classpath
com.github.gundy:semver4j:0.16.4=classpath
+com.google.android:annotations:4.1.1.4=classpath
+com.google.api.grpc:proto-google-common-protos:2.0.1=classpath
com.google.auto.value:auto-value-annotations:1.6.2=classpath
com.google.code.findbugs:jsr305:3.0.2=classpath
-com.google.code.gson:gson:2.8.6=classpath
+com.google.code.gson:gson:2.8.9=classpath
com.google.crypto.tink:tink:1.3.0-rc2=classpath
-com.google.errorprone:error_prone_annotations:2.3.4=classpath
+com.google.dagger:dagger:2.28.3=classpath
+com.google.errorprone:error_prone_annotations:2.4.0=classpath
com.google.flatbuffers:flatbuffers-java:1.12.0=classpath
com.google.guava:failureaccess:1.0.1=classpath
-com.google.guava:guava:29.0-jre=classpath
+com.google.guava:guava:30.1-jre=classpath
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=classpath
com.google.j2objc:j2objc-annotations:1.3=classpath
com.google.jimfs:jimfs:1.1=classpath
-com.google.protobuf:protobuf-java-util:3.10.0=classpath
-com.google.protobuf:protobuf-java:3.10.0=classpath
-com.google.test.platform:core-proto:0.0.2-dev=classpath
+com.google.protobuf:protobuf-java-util:3.17.2=classpath
+com.google.protobuf:protobuf-java:3.17.2=classpath
+com.google.testing.platform:core-proto:0.0.8-alpha07=classpath
com.googlecode.json-simple:json-simple:1.1=classpath
com.googlecode.juniversalchardet:juniversalchardet:1.0.3=classpath
com.squareup:javapoet:1.10.0=classpath
com.squareup:javawriter:2.5.0=classpath
com.sun.activation:javax.activation:1.2.0=classpath
-com.sun.istack:istack-commons-runtime:3.0.7=classpath
-com.sun.xml.fastinfoset:FastInfoset:1.2.15=classpath
-commons-codec:commons-codec:1.10=classpath
+com.sun.istack:istack-commons-runtime:3.0.8=classpath
+com.sun.xml.fastinfoset:FastInfoset:1.2.16=classpath
+commons-codec:commons-codec:1.11=classpath
commons-io:commons-io:2.4=classpath
commons-logging:commons-logging:1.2=classpath
de.undercouch:gradle-download-task:4.1.1=classpath
-it.unimi.dsi:fastutil:7.2.0=classpath
-javax.activation:javax.activation-api:1.2.0=classpath
+io.grpc:grpc-api:1.39.0=classpath
+io.grpc:grpc-context:1.39.0=classpath
+io.grpc:grpc-core:1.39.0=classpath
+io.grpc:grpc-netty:1.39.0=classpath
+io.grpc:grpc-protobuf-lite:1.39.0=classpath
+io.grpc:grpc-protobuf:1.39.0=classpath
+io.grpc:grpc-stub:1.39.0=classpath
+io.netty:netty-buffer:4.1.52.Final=classpath
+io.netty:netty-codec-http2:4.1.52.Final=classpath
+io.netty:netty-codec-http:4.1.52.Final=classpath
+io.netty:netty-codec-socks:4.1.52.Final=classpath
+io.netty:netty-codec:4.1.52.Final=classpath
+io.netty:netty-common:4.1.52.Final=classpath
+io.netty:netty-handler-proxy:4.1.52.Final=classpath
+io.netty:netty-handler:4.1.52.Final=classpath
+io.netty:netty-resolver:4.1.52.Final=classpath
+io.netty:netty-transport:4.1.52.Final=classpath
+io.perfmark:perfmark-api:0.23.0=classpath
+it.unimi.dsi:fastutil:8.4.0=classpath
+jakarta.activation:jakarta.activation-api:1.2.1=classpath
+jakarta.xml.bind:jakarta.xml.bind-api:2.3.2=classpath
+javax.annotation:javax.annotation-api:1.3.2=classpath
javax.inject:javax.inject:1=classpath
-javax.xml.bind:jaxb-api:2.3.1=classpath
+net.java.dev.jna:jna-platform:5.6.0=classpath
+net.java.dev.jna:jna:5.6.0=classpath
net.sf.jopt-simple:jopt-simple:4.9=classpath
net.sf.kxml:kxml2:2.3.0=classpath
-net.sf.proguard:proguard-base:6.0.3=classpath
-net.sf.proguard:proguard-gradle:6.0.3=classpath
-org.antlr:antlr4:4.5.3=classpath
-org.apache.commons:commons-compress:1.12=classpath
-org.apache.httpcomponents:httpclient:4.5.6=classpath
-org.apache.httpcomponents:httpcore:4.4.10=classpath
+org.apache.commons:commons-compress:1.20=classpath
+org.apache.httpcomponents:httpclient:4.5.13=classpath
+org.apache.httpcomponents:httpcore:4.4.13=classpath
org.apache.httpcomponents:httpmime:4.5.6=classpath
-org.bouncycastle:bcpkix-jdk15on:1.56=classpath
-org.bouncycastle:bcprov-jdk15on:1.56=classpath
-org.checkerframework:checker-qual:2.11.1=classpath
-org.glassfish.jaxb:jaxb-runtime:2.3.1=classpath
-org.glassfish.jaxb:txw2:2.3.1=classpath
+org.bitbucket.b_c:jose4j:0.7.0=classpath
+org.bouncycastle:bcpkix-jdk15on:1.67=classpath
+org.bouncycastle:bcprov-jdk15on:1.67=classpath
+org.checkerframework:checker-qual:3.5.0=classpath
+org.codehaus.mojo:animal-sniffer-annotations:1.19=classpath
+org.glassfish.jaxb:jaxb-runtime:2.3.2=classpath
+org.glassfish.jaxb:txw2:2.3.2=classpath
org.jdom:jdom2:2.0.6=classpath
-org.jetbrains.intellij.deps:trove4j:1.0.20181211=classpath
-org.jetbrains.kotlin:kotlin-android-extensions:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-annotation-processing-gradle:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-build-common:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-compiler-embeddable:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-compiler-runner:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-daemon-client:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-daemon-embeddable:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-native-utils:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-project-model:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-reflect:1.3.72=classpath
-org.jetbrains.kotlin:kotlin-scripting-common:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-scripting-jvm:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-stdlib-common:1.3.72=classpath
-org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.72=classpath
-org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.72=classpath
-org.jetbrains.kotlin:kotlin-stdlib:1.3.72=classpath
-org.jetbrains.kotlin:kotlin-tooling-metadata:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-util-io:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-util-klib:1.5.31=classpath
+org.jetbrains.intellij.deps:trove4j:1.0.20200330=classpath
+org.jetbrains.kotlin:kotlin-android-extensions:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-annotation-processing-gradle:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-build-common:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-compiler-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-compiler-runner:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-daemon-client:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-daemon-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin-idea:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-native-utils:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-project-model:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-reflect:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-scripting-common:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-scripting-jvm:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-stdlib-common:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-stdlib:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-tooling-core:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-tooling-metadata:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-util-io:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-util-klib:1.7.10=classpath
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.0=classpath
-org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0=classpath
-org.jetbrains.trove4j:trove4j:20160824=classpath
org.jetbrains:annotations:13.0=classpath
org.json:json:20180813=classpath
-org.jvnet.staxex:stax-ex:1.8=classpath
-org.ow2.asm:asm-analysis:7.0=classpath
-org.ow2.asm:asm-commons:7.0=classpath
-org.ow2.asm:asm-tree:7.0=classpath
-org.ow2.asm:asm-util:7.0=classpath
-org.ow2.asm:asm:7.0=classpath
-org.tensorflow:tensorflow-lite-metadata:0.1.0-rc1=classpath
+org.jvnet.staxex:stax-ex:1.8.1=classpath
+org.ow2.asm:asm-analysis:9.1=classpath
+org.ow2.asm:asm-commons:9.1=classpath
+org.ow2.asm:asm-tree:9.1=classpath
+org.ow2.asm:asm-util:9.1=classpath
+org.ow2.asm:asm:9.1=classpath
+org.slf4j:slf4j-api:1.7.30=classpath
+org.tensorflow:tensorflow-lite-metadata:0.1.0-rc2=classpath
+xerces:xercesImpl:2.12.0=classpath
+xml-apis:xml-apis:1.4.01=classpath
empty=
diff --git a/dev/integration_tests/release_smoke_test/android/project-app.lockfile b/dev/integration_tests/release_smoke_test/android/project-app.lockfile
index 2622456..f496f6d 100644
--- a/dev/integration_tests/release_smoke_test/android/project-app.lockfile
+++ b/dev/integration_tests/release_smoke_test/android/project-app.lockfile
@@ -26,8 +26,8 @@
androidx.tracing:tracing:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
androidx.versionedparcelable:versionedparcelable:1.1.1=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
androidx.viewpager:viewpager:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
-androidx.window:window-java:1.0.0-beta03=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
-androidx.window:window:1.0.0-beta03=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.window:window-java:1.0.0-beta04=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.window:window:1.0.0-beta04=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
com.android.tools.analytics-library:protos:27.1.3=lintClassPath
com.android.tools.analytics-library:shared:27.1.3=lintClassPath
com.android.tools.analytics-library:tracker:27.1.3=lintClassPath
@@ -100,6 +100,10 @@
org.hamcrest:hamcrest-core:1.3=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.hamcrest:hamcrest-integration:1.3=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.hamcrest:hamcrest-library:1.3=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jacoco:org.jacoco.agent:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.ant:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.core:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.report:0.8.7=androidJacocoAnt
org.jetbrains.kotlin:kotlin-reflect:1.3.72=lintClassPath
org.jetbrains.kotlin:kotlin-stdlib-common:1.3.72=lintClassPath
org.jetbrains.kotlin:kotlin-stdlib-common:1.5.31=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
@@ -116,8 +120,12 @@
org.jetbrains:annotations:13.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,lintClassPath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.jvnet.staxex:stax-ex:1.8=lintClassPath
org.ow2.asm:asm-analysis:7.0=lintClassPath
+org.ow2.asm:asm-analysis:9.1=androidJacocoAnt
org.ow2.asm:asm-commons:7.0=lintClassPath
+org.ow2.asm:asm-commons:9.1=androidJacocoAnt
org.ow2.asm:asm-tree:7.0=lintClassPath
+org.ow2.asm:asm-tree:9.1=androidJacocoAnt
org.ow2.asm:asm-util:7.0=lintClassPath
org.ow2.asm:asm:7.0=lintClassPath
-empty=androidApis,androidTestUtil,compile,coreLibraryDesugaring,debugAndroidTestAnnotationProcessorClasspath,debugAnnotationProcessorClasspath,debugReverseMetadataValues,debugUnitTestAnnotationProcessorClasspath,debugWearBundling,lintChecks,lintPublish,profileAnnotationProcessorClasspath,profileReverseMetadataValues,profileUnitTestAnnotationProcessorClasspath,profileWearBundling,releaseAnnotationProcessorClasspath,releaseReverseMetadataValues,releaseUnitTestAnnotationProcessorClasspath,releaseWearBundling,testCompile
+org.ow2.asm:asm:9.1=androidJacocoAnt
+empty=androidApis,androidJdkImage,androidTestUtil,compile,coreLibraryDesugaring,debugAndroidTestAnnotationProcessorClasspath,debugAnnotationProcessorClasspath,debugReverseMetadataValues,debugUnitTestAnnotationProcessorClasspath,debugWearBundling,lintChecks,lintPublish,profileAnnotationProcessorClasspath,profileReverseMetadataValues,profileUnitTestAnnotationProcessorClasspath,profileWearBundling,releaseAnnotationProcessorClasspath,releaseReverseMetadataValues,releaseUnitTestAnnotationProcessorClasspath,releaseWearBundling,testCompile
diff --git a/dev/integration_tests/release_smoke_test/android/project-integration_test.lockfile b/dev/integration_tests/release_smoke_test/android/project-integration_test.lockfile
index ca99c9e..79f963c 100644
--- a/dev/integration_tests/release_smoke_test/android/project-integration_test.lockfile
+++ b/dev/integration_tests/release_smoke_test/android/project-integration_test.lockfile
@@ -26,8 +26,8 @@
androidx.tracing:tracing:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
androidx.versionedparcelable:versionedparcelable:1.1.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
androidx.viewpager:viewpager:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
-androidx.window:window-java:1.0.0-beta03=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
-androidx.window:window:1.0.0-beta03=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.window:window-java:1.0.0-beta04=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.window:window:1.0.0-beta04=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
com.android.tools.analytics-library:protos:27.1.3=lintClassPath
com.android.tools.analytics-library:shared:27.1.3=lintClassPath
com.android.tools.analytics-library:tracker:27.1.3=lintClassPath
@@ -99,6 +99,10 @@
org.hamcrest:hamcrest-core:1.3=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.hamcrest:hamcrest-integration:1.3=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.hamcrest:hamcrest-library:1.3=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jacoco:org.jacoco.agent:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.ant:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.core:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.report:0.8.7=androidJacocoAnt
org.jetbrains.kotlin:kotlin-reflect:1.3.72=lintClassPath
org.jetbrains.kotlin:kotlin-stdlib-common:1.3.72=lintClassPath
org.jetbrains.kotlin:kotlin-stdlib-common:1.5.31=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
@@ -115,8 +119,12 @@
org.jetbrains:annotations:13.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,lintClassPath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.jvnet.staxex:stax-ex:1.8=lintClassPath
org.ow2.asm:asm-analysis:7.0=lintClassPath
+org.ow2.asm:asm-analysis:9.1=androidJacocoAnt
org.ow2.asm:asm-commons:7.0=lintClassPath
+org.ow2.asm:asm-commons:9.1=androidJacocoAnt
org.ow2.asm:asm-tree:7.0=lintClassPath
+org.ow2.asm:asm-tree:9.1=androidJacocoAnt
org.ow2.asm:asm-util:7.0=lintClassPath
org.ow2.asm:asm:7.0=lintClassPath
-empty=androidApis,androidTestUtil,compile,coreLibraryDesugaring,debugAndroidTestAnnotationProcessorClasspath,debugAnnotationProcessorClasspath,debugUnitTestAnnotationProcessorClasspath,lintChecks,lintPublish,profileAnnotationProcessorClasspath,profileUnitTestAnnotationProcessorClasspath,releaseAnnotationProcessorClasspath,releaseUnitTestAnnotationProcessorClasspath,testCompile
+org.ow2.asm:asm:9.1=androidJacocoAnt
+empty=androidApis,androidJdkImage,androidTestUtil,compile,coreLibraryDesugaring,debugAndroidTestAnnotationProcessorClasspath,debugAnnotationProcessorClasspath,debugUnitTestAnnotationProcessorClasspath,lintChecks,lintPublish,profileAnnotationProcessorClasspath,profileUnitTestAnnotationProcessorClasspath,releaseAnnotationProcessorClasspath,releaseUnitTestAnnotationProcessorClasspath,testCompile
diff --git a/dev/integration_tests/release_smoke_test/android/settings.gradle b/dev/integration_tests/release_smoke_test/android/settings.gradle
index 03ae72d..a020595 100644
--- a/dev/integration_tests/release_smoke_test/android/settings.gradle
+++ b/dev/integration_tests/release_smoke_test/android/settings.gradle
@@ -8,8 +8,6 @@
include ':app'
-enableFeaturePreview('ONE_LOCKFILE_PER_PROJECT')
-
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()
diff --git a/dev/integration_tests/release_smoke_test/ios/Runner/Info.plist b/dev/integration_tests/release_smoke_test/ios/Runner/Info.plist
index b6f13ec..36a79fa 100644
--- a/dev/integration_tests/release_smoke_test/ios/Runner/Info.plist
+++ b/dev/integration_tests/release_smoke_test/ios/Runner/Info.plist
@@ -39,8 +39,6 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
- <key>UIViewControllerBasedStatusBarAppearance</key>
- <false/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
diff --git a/dev/integration_tests/release_smoke_test/pubspec.yaml b/dev/integration_tests/release_smoke_test/pubspec.yaml
index 8329ea1..2bc9222 100644
--- a/dev/integration_tests/release_smoke_test/pubspec.yaml
+++ b/dev/integration_tests/release_smoke_test/pubspec.yaml
@@ -9,10 +9,10 @@
characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
collection: 1.17.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.9.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
flutter_test:
@@ -27,11 +27,11 @@
matcher: 0.12.16 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path: 1.8.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- vm_service: 11.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ vm_service: 11.7.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
-# PUBSPEC CHECKSUM: 39d4
+# PUBSPEC CHECKSUM: 07fe
diff --git a/dev/integration_tests/spell_check/android/build.gradle b/dev/integration_tests/spell_check/android/build.gradle
index b843584..a2a8866 100644
--- a/dev/integration_tests/spell_check/android/build.gradle
+++ b/dev/integration_tests/spell_check/android/build.gradle
@@ -2,17 +2,25 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// This file is auto generated.
+// To update all the build.gradle files in the Flutter repo,
+// See dev/tools/bin/generate_gradle_lockfiles.dart.
+
buildscript {
- ext.kotlin_version = '1.6.10'
+ ext.kotlin_version = '1.7.10'
repositories {
google()
mavenCentral()
}
dependencies {
- classpath 'com.android.tools.build:gradle:7.1.2'
+ classpath 'com.android.tools.build:gradle:7.3.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
+
+ configurations.classpath {
+ resolutionStrategy.activateDependencyLocking()
+ }
}
allprojects {
@@ -23,11 +31,19 @@
}
rootProject.buildDir = '../build'
+
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
project.evaluationDependsOn(':app')
+ dependencyLocking {
+ ignoredDependencies.add('io.flutter:*')
+ lockFile = file("${rootProject.projectDir}/project-${project.name}.lockfile")
+ if (!project.hasProperty('local-engine-repo')) {
+ lockAllConfigurations()
+ }
+ }
}
tasks.register("clean", Delete) {
diff --git a/dev/integration_tests/spell_check/android/buildscript-gradle.lockfile b/dev/integration_tests/spell_check/android/buildscript-gradle.lockfile
new file mode 100644
index 0000000..eb60580
--- /dev/null
+++ b/dev/integration_tests/spell_check/android/buildscript-gradle.lockfile
@@ -0,0 +1,152 @@
+# This is a Gradle generated file for dependency locking.
+# Manual edits can break the build and are not advised.
+# This file is expected to be part of source control.
+androidx.databinding:databinding-common:7.3.0=classpath
+androidx.databinding:databinding-compiler-common:7.3.0=classpath
+com.android.databinding:baseLibrary:7.3.0=classpath
+com.android.tools.analytics-library:crash:30.3.0=classpath
+com.android.tools.analytics-library:protos:30.3.0=classpath
+com.android.tools.analytics-library:shared:30.3.0=classpath
+com.android.tools.analytics-library:tracker:30.3.0=classpath
+com.android.tools.build.jetifier:jetifier-core:1.0.0-beta10=classpath
+com.android.tools.build.jetifier:jetifier-processor:1.0.0-beta10=classpath
+com.android.tools.build:aapt2-proto:7.3.0-8691043=classpath
+com.android.tools.build:aaptcompiler:7.3.0=classpath
+com.android.tools.build:apksig:7.3.0=classpath
+com.android.tools.build:apkzlib:7.3.0=classpath
+com.android.tools.build:builder-model:7.3.0=classpath
+com.android.tools.build:builder-test-api:7.3.0=classpath
+com.android.tools.build:builder:7.3.0=classpath
+com.android.tools.build:bundletool:1.9.0=classpath
+com.android.tools.build:gradle-api:7.3.0=classpath
+com.android.tools.build:gradle:7.3.0=classpath
+com.android.tools.build:manifest-merger:30.3.0=classpath
+com.android.tools.build:transform-api:2.0.0-deprecated-use-gradle-api=classpath
+com.android.tools.ddms:ddmlib:30.3.0=classpath
+com.android.tools.layoutlib:layoutlib-api:30.3.0=classpath
+com.android.tools.lint:lint-model:30.3.0=classpath
+com.android.tools.lint:lint-typedef-remover:30.3.0=classpath
+com.android.tools.utp:android-device-provider-ddmlib-proto:30.3.0=classpath
+com.android.tools.utp:android-device-provider-gradle-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-host-additional-test-output-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-host-coverage-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-host-retention-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-result-listener-gradle-proto:30.3.0=classpath
+com.android.tools:annotations:30.3.0=classpath
+com.android.tools:common:30.3.0=classpath
+com.android.tools:dvlib:30.3.0=classpath
+com.android.tools:repository:30.3.0=classpath
+com.android.tools:sdk-common:30.3.0=classpath
+com.android.tools:sdklib:30.3.0=classpath
+com.android:signflinger:7.3.0=classpath
+com.android:zipflinger:7.3.0=classpath
+com.github.gundy:semver4j:0.16.4=classpath
+com.google.android:annotations:4.1.1.4=classpath
+com.google.api.grpc:proto-google-common-protos:2.0.1=classpath
+com.google.auto.value:auto-value-annotations:1.6.2=classpath
+com.google.code.findbugs:jsr305:3.0.2=classpath
+com.google.code.gson:gson:2.8.9=classpath
+com.google.crypto.tink:tink:1.3.0-rc2=classpath
+com.google.dagger:dagger:2.28.3=classpath
+com.google.errorprone:error_prone_annotations:2.4.0=classpath
+com.google.flatbuffers:flatbuffers-java:1.12.0=classpath
+com.google.guava:failureaccess:1.0.1=classpath
+com.google.guava:guava:30.1-jre=classpath
+com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=classpath
+com.google.j2objc:j2objc-annotations:1.3=classpath
+com.google.jimfs:jimfs:1.1=classpath
+com.google.protobuf:protobuf-java-util:3.17.2=classpath
+com.google.protobuf:protobuf-java:3.17.2=classpath
+com.google.testing.platform:core-proto:0.0.8-alpha07=classpath
+com.googlecode.json-simple:json-simple:1.1=classpath
+com.googlecode.juniversalchardet:juniversalchardet:1.0.3=classpath
+com.squareup:javapoet:1.10.0=classpath
+com.squareup:javawriter:2.5.0=classpath
+com.sun.activation:javax.activation:1.2.0=classpath
+com.sun.istack:istack-commons-runtime:3.0.8=classpath
+com.sun.xml.fastinfoset:FastInfoset:1.2.16=classpath
+commons-codec:commons-codec:1.11=classpath
+commons-io:commons-io:2.4=classpath
+commons-logging:commons-logging:1.2=classpath
+de.undercouch:gradle-download-task:4.1.1=classpath
+io.grpc:grpc-api:1.39.0=classpath
+io.grpc:grpc-context:1.39.0=classpath
+io.grpc:grpc-core:1.39.0=classpath
+io.grpc:grpc-netty:1.39.0=classpath
+io.grpc:grpc-protobuf-lite:1.39.0=classpath
+io.grpc:grpc-protobuf:1.39.0=classpath
+io.grpc:grpc-stub:1.39.0=classpath
+io.netty:netty-buffer:4.1.52.Final=classpath
+io.netty:netty-codec-http2:4.1.52.Final=classpath
+io.netty:netty-codec-http:4.1.52.Final=classpath
+io.netty:netty-codec-socks:4.1.52.Final=classpath
+io.netty:netty-codec:4.1.52.Final=classpath
+io.netty:netty-common:4.1.52.Final=classpath
+io.netty:netty-handler-proxy:4.1.52.Final=classpath
+io.netty:netty-handler:4.1.52.Final=classpath
+io.netty:netty-resolver:4.1.52.Final=classpath
+io.netty:netty-transport:4.1.52.Final=classpath
+io.perfmark:perfmark-api:0.23.0=classpath
+it.unimi.dsi:fastutil:8.4.0=classpath
+jakarta.activation:jakarta.activation-api:1.2.1=classpath
+jakarta.xml.bind:jakarta.xml.bind-api:2.3.2=classpath
+javax.annotation:javax.annotation-api:1.3.2=classpath
+javax.inject:javax.inject:1=classpath
+net.java.dev.jna:jna-platform:5.6.0=classpath
+net.java.dev.jna:jna:5.6.0=classpath
+net.sf.jopt-simple:jopt-simple:4.9=classpath
+net.sf.kxml:kxml2:2.3.0=classpath
+org.apache.commons:commons-compress:1.20=classpath
+org.apache.httpcomponents:httpclient:4.5.13=classpath
+org.apache.httpcomponents:httpcore:4.4.13=classpath
+org.apache.httpcomponents:httpmime:4.5.6=classpath
+org.bitbucket.b_c:jose4j:0.7.0=classpath
+org.bouncycastle:bcpkix-jdk15on:1.67=classpath
+org.bouncycastle:bcprov-jdk15on:1.67=classpath
+org.checkerframework:checker-qual:3.5.0=classpath
+org.codehaus.mojo:animal-sniffer-annotations:1.19=classpath
+org.glassfish.jaxb:jaxb-runtime:2.3.2=classpath
+org.glassfish.jaxb:txw2:2.3.2=classpath
+org.jdom:jdom2:2.0.6=classpath
+org.jetbrains.intellij.deps:trove4j:1.0.20200330=classpath
+org.jetbrains.kotlin:kotlin-android-extensions:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-annotation-processing-gradle:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-build-common:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-compiler-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-compiler-runner:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-daemon-client:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-daemon-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin-idea:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-native-utils:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-project-model:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-reflect:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-scripting-common:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-scripting-jvm:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-stdlib-common:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-stdlib:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-tooling-core:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-tooling-metadata:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-util-io:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-util-klib:1.7.10=classpath
+org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.0=classpath
+org.jetbrains:annotations:13.0=classpath
+org.json:json:20180813=classpath
+org.jvnet.staxex:stax-ex:1.8.1=classpath
+org.ow2.asm:asm-analysis:9.1=classpath
+org.ow2.asm:asm-commons:9.1=classpath
+org.ow2.asm:asm-tree:9.1=classpath
+org.ow2.asm:asm-util:9.1=classpath
+org.ow2.asm:asm:9.1=classpath
+org.slf4j:slf4j-api:1.7.30=classpath
+org.tensorflow:tensorflow-lite-metadata:0.1.0-rc2=classpath
+xerces:xercesImpl:2.12.0=classpath
+xml-apis:xml-apis:1.4.01=classpath
+empty=
diff --git a/dev/integration_tests/spell_check/android/project-app.lockfile b/dev/integration_tests/spell_check/android/project-app.lockfile
new file mode 100644
index 0000000..33db6f2
--- /dev/null
+++ b/dev/integration_tests/spell_check/android/project-app.lockfile
@@ -0,0 +1,70 @@
+# This is a Gradle generated file for dependency locking.
+# Manual edits can break the build and are not advised.
+# This file is expected to be part of source control.
+androidx.activity:activity:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.annotation:annotation-experimental:1.1.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.annotation:annotation:1.2.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.arch.core:core-common:2.1.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.arch.core:core-runtime:2.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.collection:collection:1.1.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.core:core:1.6.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.customview:customview:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.fragment:fragment:1.1.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.lifecycle:lifecycle-common-java8:2.2.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.lifecycle:lifecycle-common:2.2.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.lifecycle:lifecycle-livedata-core:2.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.lifecycle:lifecycle-livedata:2.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.lifecycle:lifecycle-runtime:2.2.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.lifecycle:lifecycle-viewmodel:2.1.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.loader:loader:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.savedstate:savedstate:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.test.espresso:espresso-core:3.2.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.test.espresso:espresso-idling-resource:3.2.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.test:monitor:1.2.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.test:rules:1.2.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.test:runner:1.2.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.tracing:tracing:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.versionedparcelable:versionedparcelable:1.1.1=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.viewpager:viewpager:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.window:window-java:1.0.0-beta04=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.window:window:1.0.0-beta04=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+com.google.code.findbugs:jsr305:2.0.1=debugAndroidTestCompileClasspath
+com.google.code.findbugs:jsr305:3.0.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+com.google.errorprone:error_prone_annotations:2.3.2=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,profileRuntimeClasspath,profileUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath
+com.google.guava:failureaccess:1.0.1=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,profileRuntimeClasspath,profileUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath
+com.google.guava:guava:28.1-android=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,profileRuntimeClasspath,profileUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath
+com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,profileRuntimeClasspath,profileUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath
+com.google.j2objc:j2objc-annotations:1.3=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,profileRuntimeClasspath,profileUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath
+com.squareup:javawriter:2.1.1=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+javax.inject:javax.inject:1=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+junit:junit:4.12=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+net.java.dev.jna:jna:5.6.0=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
+net.sf.kxml:kxml2:2.3.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.checkerframework:checker-compat-qual:2.5.5=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,profileRuntimeClasspath,profileUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath
+org.codehaus.mojo:animal-sniffer-annotations:1.18=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,profileRuntimeClasspath,profileUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath
+org.hamcrest:hamcrest-core:1.3=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.hamcrest:hamcrest-integration:1.3=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.hamcrest:hamcrest-library:1.3=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jacoco:org.jacoco.agent:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.ant:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.core:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.report:0.8.7=androidJacocoAnt
+org.jetbrains.intellij.deps:trove4j:1.0.20200330=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
+org.jetbrains.kotlin:kotlin-compiler-embeddable:1.7.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
+org.jetbrains.kotlin:kotlin-daemon-embeddable:1.7.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
+org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:1.7.10=kotlinKlibCommonizerClasspath
+org.jetbrains.kotlin:kotlin-reflect:1.7.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
+org.jetbrains.kotlin:kotlin-script-runtime:1.7.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
+org.jetbrains.kotlin:kotlin-stdlib-common:1.7.10=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.10=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.30=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlin:kotlin-stdlib:1.7.10=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.2=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains:annotations:13.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.ow2.asm:asm-analysis:9.1=androidJacocoAnt
+org.ow2.asm:asm-commons:9.1=androidJacocoAnt
+org.ow2.asm:asm-tree:9.1=androidJacocoAnt
+org.ow2.asm:asm:9.1=androidJacocoAnt
+empty=androidApis,androidJdkImage,androidTestApiDependenciesMetadata,androidTestCompileOnlyDependenciesMetadata,androidTestDebugApiDependenciesMetadata,androidTestDebugCompileOnlyDependenciesMetadata,androidTestDebugImplementationDependenciesMetadata,androidTestDebugIntransitiveDependenciesMetadata,androidTestDebugRuntimeOnlyDependenciesMetadata,androidTestImplementationDependenciesMetadata,androidTestIntransitiveDependenciesMetadata,androidTestProfileApiDependenciesMetadata,androidTestProfileCompileOnlyDependenciesMetadata,androidTestProfileImplementationDependenciesMetadata,androidTestProfileIntransitiveDependenciesMetadata,androidTestProfileRuntimeOnlyDependenciesMetadata,androidTestReleaseApiDependenciesMetadata,androidTestReleaseCompileOnlyDependenciesMetadata,androidTestReleaseImplementationDependenciesMetadata,androidTestReleaseIntransitiveDependenciesMetadata,androidTestReleaseRuntimeOnlyDependenciesMetadata,androidTestRuntimeOnlyDependenciesMetadata,androidTestUtil,compileOnlyDependenciesMetadata,coreLibraryDesugaring,debugAndroidTestAnnotationProcessorClasspath,debugAndroidTestApiDependenciesMetadata,debugAndroidTestCompileOnlyDependenciesMetadata,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestIntransitiveDependenciesMetadata,debugAndroidTestRuntimeClasspath,debugAndroidTestRuntimeOnlyDependenciesMetadata,debugAnnotationProcessorClasspath,debugCompileOnlyDependenciesMetadata,debugIntransitiveDependenciesMetadata,debugReverseMetadataValues,debugRuntimeOnlyDependenciesMetadata,debugUnitTestAnnotationProcessorClasspath,debugUnitTestApiDependenciesMetadata,debugUnitTestCompileOnlyDependenciesMetadata,debugUnitTestImplementationDependenciesMetadata,debugUnitTestIntransitiveDependenciesMetadata,debugUnitTestRuntimeOnlyDependenciesMetadata,debugWearBundling,intransitiveDependenciesMetadata,kotlinCompilerPluginClasspath,kotlinCompilerPluginClasspathDebug,kotlinCompilerPluginClasspathDebugAndroidTest,kotlinCompilerPluginClasspathDebugUnitTest,kotlinCompilerPluginClasspathProfile,kotlinCompilerPluginClasspathProfileUnitTest,kotlinCompilerPluginClasspathRelease,kotlinCompilerPluginClasspathReleaseUnitTest,kotlinNativeCompilerPluginClasspath,lintChecks,lintPublish,profileAnnotationProcessorClasspath,profileCompileOnlyDependenciesMetadata,profileIntransitiveDependenciesMetadata,profileReverseMetadataValues,profileRuntimeOnlyDependenciesMetadata,profileUnitTestAnnotationProcessorClasspath,profileUnitTestApiDependenciesMetadata,profileUnitTestCompileOnlyDependenciesMetadata,profileUnitTestImplementationDependenciesMetadata,profileUnitTestIntransitiveDependenciesMetadata,profileUnitTestRuntimeOnlyDependenciesMetadata,profileWearBundling,releaseAnnotationProcessorClasspath,releaseCompileOnlyDependenciesMetadata,releaseIntransitiveDependenciesMetadata,releaseReverseMetadataValues,releaseRuntimeOnlyDependenciesMetadata,releaseUnitTestAnnotationProcessorClasspath,releaseUnitTestApiDependenciesMetadata,releaseUnitTestCompileOnlyDependenciesMetadata,releaseUnitTestImplementationDependenciesMetadata,releaseUnitTestIntransitiveDependenciesMetadata,releaseUnitTestRuntimeOnlyDependenciesMetadata,releaseWearBundling,runtimeOnlyDependenciesMetadata,testApiDependenciesMetadata,testCompileOnlyDependenciesMetadata,testDebugApiDependenciesMetadata,testDebugCompileOnlyDependenciesMetadata,testDebugImplementationDependenciesMetadata,testDebugIntransitiveDependenciesMetadata,testDebugRuntimeOnlyDependenciesMetadata,testFixturesApiDependenciesMetadata,testFixturesCompileOnlyDependenciesMetadata,testFixturesDebugApiDependenciesMetadata,testFixturesDebugCompileOnlyDependenciesMetadata,testFixturesDebugImplementationDependenciesMetadata,testFixturesDebugIntransitiveDependenciesMetadata,testFixturesDebugRuntimeOnlyDependenciesMetadata,testFixturesImplementationDependenciesMetadata,testFixturesIntransitiveDependenciesMetadata,testFixturesProfileApiDependenciesMetadata,testFixturesProfileCompileOnlyDependenciesMetadata,testFixturesProfileImplementationDependenciesMetadata,testFixturesProfileIntransitiveDependenciesMetadata,testFixturesProfileRuntimeOnlyDependenciesMetadata,testFixturesReleaseApiDependenciesMetadata,testFixturesReleaseCompileOnlyDependenciesMetadata,testFixturesReleaseImplementationDependenciesMetadata,testFixturesReleaseIntransitiveDependenciesMetadata,testFixturesReleaseRuntimeOnlyDependenciesMetadata,testFixturesRuntimeOnlyDependenciesMetadata,testImplementationDependenciesMetadata,testIntransitiveDependenciesMetadata,testProfileApiDependenciesMetadata,testProfileCompileOnlyDependenciesMetadata,testProfileImplementationDependenciesMetadata,testProfileIntransitiveDependenciesMetadata,testProfileRuntimeOnlyDependenciesMetadata,testReleaseApiDependenciesMetadata,testReleaseCompileOnlyDependenciesMetadata,testReleaseImplementationDependenciesMetadata,testReleaseIntransitiveDependenciesMetadata,testReleaseRuntimeOnlyDependenciesMetadata,testRuntimeOnlyDependenciesMetadata
diff --git a/dev/integration_tests/spell_check/android/project-integration_test.lockfile b/dev/integration_tests/spell_check/android/project-integration_test.lockfile
new file mode 100644
index 0000000..f45da3d
--- /dev/null
+++ b/dev/integration_tests/spell_check/android/project-integration_test.lockfile
@@ -0,0 +1,62 @@
+# This is a Gradle generated file for dependency locking.
+# Manual edits can break the build and are not advised.
+# This file is expected to be part of source control.
+androidx.activity:activity:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.annotation:annotation-experimental:1.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.annotation:annotation:1.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.arch.core:core-common:2.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.arch.core:core-runtime:2.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.collection:collection:1.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.core:core:1.6.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.customview:customview:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.fragment:fragment:1.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.lifecycle:lifecycle-common-java8:2.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.lifecycle:lifecycle-common:2.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.lifecycle:lifecycle-livedata-core:2.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.lifecycle:lifecycle-livedata:2.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.lifecycle:lifecycle-runtime:2.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.lifecycle:lifecycle-viewmodel:2.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.loader:loader:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.savedstate:savedstate:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.test.espresso:espresso-core:3.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.test.espresso:espresso-idling-resource:3.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.test:monitor:1.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.test:rules:1.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.test:runner:1.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.tracing:tracing:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.versionedparcelable:versionedparcelable:1.1.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.viewpager:viewpager:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.window:window-java:1.0.0-beta04=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+androidx.window:window:1.0.0-beta04=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+com.google.code.findbugs:jsr305:3.0.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+com.google.errorprone:error_prone_annotations:2.3.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+com.google.guava:failureaccess:1.0.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+com.google.guava:guava:28.1-android=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+com.google.j2objc:j2objc-annotations:1.3=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+com.squareup:javawriter:2.1.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+javax.inject:javax.inject:1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+junit:junit:4.12=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+net.sf.kxml:kxml2:2.3.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.checkerframework:checker-compat-qual:2.5.5=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.codehaus.mojo:animal-sniffer-annotations:1.18=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.hamcrest:hamcrest-core:1.3=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.hamcrest:hamcrest-integration:1.3=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.hamcrest:hamcrest-library:1.3=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jacoco:org.jacoco.agent:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.ant:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.core:0.8.7=androidJacocoAnt
+org.jacoco:org.jacoco.report:0.8.7=androidJacocoAnt
+org.jetbrains.kotlin:kotlin-stdlib-common:1.5.31=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.5.30=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.30=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlin:kotlin-stdlib:1.5.31=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.jetbrains:annotations:13.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,profileCompileClasspath,profileRuntimeClasspath,profileUnitTestCompileClasspath,profileUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
+org.ow2.asm:asm-analysis:9.1=androidJacocoAnt
+org.ow2.asm:asm-commons:9.1=androidJacocoAnt
+org.ow2.asm:asm-tree:9.1=androidJacocoAnt
+org.ow2.asm:asm:9.1=androidJacocoAnt
+empty=androidApis,androidJdkImage,androidTestUtil,coreLibraryDesugaring,debugAndroidTestAnnotationProcessorClasspath,debugAnnotationProcessorClasspath,debugUnitTestAnnotationProcessorClasspath,lintChecks,lintPublish,profileAnnotationProcessorClasspath,profileUnitTestAnnotationProcessorClasspath,releaseAnnotationProcessorClasspath,releaseUnitTestAnnotationProcessorClasspath
diff --git a/dev/integration_tests/spell_check/android/settings.gradle b/dev/integration_tests/spell_check/android/settings.gradle
index d3b6a40..a020595 100644
--- a/dev/integration_tests/spell_check/android/settings.gradle
+++ b/dev/integration_tests/spell_check/android/settings.gradle
@@ -2,6 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// This file is auto generated.
+// To update all the settings.gradle files in the Flutter repo,
+// See dev/tools/bin/generate_gradle_lockfiles.dart.
+
include ':app'
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
diff --git a/dev/integration_tests/spell_check/ios/Runner/Info.plist b/dev/integration_tests/spell_check/ios/Runner/Info.plist
index 7d0689b..7e76560 100644
--- a/dev/integration_tests/spell_check/ios/Runner/Info.plist
+++ b/dev/integration_tests/spell_check/ios/Runner/Info.plist
@@ -41,8 +41,6 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
- <key>UIViewControllerBasedStatusBarAppearance</key>
- <false/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
diff --git a/dev/integration_tests/spell_check/pubspec.yaml b/dev/integration_tests/spell_check/pubspec.yaml
index bfa6b9a..cf9b04a 100644
--- a/dev/integration_tests/spell_check/pubspec.yaml
+++ b/dev/integration_tests/spell_check/pubspec.yaml
@@ -36,10 +36,10 @@
characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
collection: 1.17.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.9.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
flutter_test:
@@ -61,12 +61,12 @@
matcher: 0.12.16 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path: 1.8.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- vm_service: 11.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ vm_service: 11.7.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
flutter:
@@ -106,4 +106,4 @@
# For details regarding fonts from package dependencies,
# see https://flutter.dev/custom-fonts/#from-packages
-# PUBSPEC CHECKSUM: 307c
+# PUBSPEC CHECKSUM: d9a6
diff --git a/dev/integration_tests/ui/android/build.gradle b/dev/integration_tests/ui/android/build.gradle
index 2de2062..a2a8866 100644
--- a/dev/integration_tests/ui/android/build.gradle
+++ b/dev/integration_tests/ui/android/build.gradle
@@ -7,14 +7,14 @@
// See dev/tools/bin/generate_gradle_lockfiles.dart.
buildscript {
- ext.kotlin_version = '1.5.31'
+ ext.kotlin_version = '1.7.10'
repositories {
google()
mavenCentral()
}
dependencies {
- classpath 'com.android.tools.build:gradle:7.2.0'
+ classpath 'com.android.tools.build:gradle:7.3.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
diff --git a/dev/integration_tests/ui/android/buildscript-gradle.lockfile b/dev/integration_tests/ui/android/buildscript-gradle.lockfile
index efe1327..eb60580 100644
--- a/dev/integration_tests/ui/android/buildscript-gradle.lockfile
+++ b/dev/integration_tests/ui/android/buildscript-gradle.lockfile
@@ -1,69 +1,62 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
-androidx.databinding:databinding-common:7.2.0=classpath
-androidx.databinding:databinding-compiler-common:7.2.0=classpath
-com.android.databinding:baseLibrary:7.2.0=classpath
-com.android.tools.analytics-library:crash:30.2.0=classpath
-com.android.tools.analytics-library:protos:30.2.0=classpath
-com.android.tools.analytics-library:shared:30.2.0=classpath
-com.android.tools.analytics-library:tracker:30.2.0=classpath
-com.android.tools.build.jetifier:jetifier-core:1.0.0-beta09=classpath
-com.android.tools.build.jetifier:jetifier-processor:1.0.0-beta09=classpath
-com.android.tools.build:aapt2-proto:7.2.0-7984345=classpath
-com.android.tools.build:aaptcompiler:7.2.0=classpath
-com.android.tools.build:apksig:7.2.0=classpath
-com.android.tools.build:apkzlib:7.2.0=classpath
-com.android.tools.build:builder-model:7.2.0=classpath
-com.android.tools.build:builder-test-api:7.2.0=classpath
-com.android.tools.build:builder:7.2.0=classpath
-com.android.tools.build:bundletool:1.8.2=classpath
-com.android.tools.build:gradle-api:7.2.0=classpath
-com.android.tools.build:gradle:7.2.0=classpath
-com.android.tools.build:manifest-merger:30.2.0=classpath
+androidx.databinding:databinding-common:7.3.0=classpath
+androidx.databinding:databinding-compiler-common:7.3.0=classpath
+com.android.databinding:baseLibrary:7.3.0=classpath
+com.android.tools.analytics-library:crash:30.3.0=classpath
+com.android.tools.analytics-library:protos:30.3.0=classpath
+com.android.tools.analytics-library:shared:30.3.0=classpath
+com.android.tools.analytics-library:tracker:30.3.0=classpath
+com.android.tools.build.jetifier:jetifier-core:1.0.0-beta10=classpath
+com.android.tools.build.jetifier:jetifier-processor:1.0.0-beta10=classpath
+com.android.tools.build:aapt2-proto:7.3.0-8691043=classpath
+com.android.tools.build:aaptcompiler:7.3.0=classpath
+com.android.tools.build:apksig:7.3.0=classpath
+com.android.tools.build:apkzlib:7.3.0=classpath
+com.android.tools.build:builder-model:7.3.0=classpath
+com.android.tools.build:builder-test-api:7.3.0=classpath
+com.android.tools.build:builder:7.3.0=classpath
+com.android.tools.build:bundletool:1.9.0=classpath
+com.android.tools.build:gradle-api:7.3.0=classpath
+com.android.tools.build:gradle:7.3.0=classpath
+com.android.tools.build:manifest-merger:30.3.0=classpath
com.android.tools.build:transform-api:2.0.0-deprecated-use-gradle-api=classpath
-com.android.tools.ddms:ddmlib:30.2.0=classpath
-com.android.tools.layoutlib:layoutlib-api:30.2.0=classpath
-com.android.tools.lint:lint-model:30.2.0=classpath
-com.android.tools.lint:lint-typedef-remover:30.2.0=classpath
-com.android.tools.utp:android-device-provider-ddmlib-proto:30.2.0=classpath
-com.android.tools.utp:android-device-provider-gradle-proto:30.2.0=classpath
-com.android.tools.utp:android-test-plugin-host-additional-test-output-proto:30.2.0=classpath
-com.android.tools.utp:android-test-plugin-host-coverage-proto:30.2.0=classpath
-com.android.tools.utp:android-test-plugin-host-retention-proto:30.2.0=classpath
-com.android.tools.utp:android-test-plugin-result-listener-gradle-proto:30.2.0=classpath
-com.android.tools:annotations:30.2.0=classpath
-com.android.tools:common:30.2.0=classpath
-com.android.tools:dvlib:30.2.0=classpath
-com.android.tools:repository:30.2.0=classpath
-com.android.tools:sdk-common:30.2.0=classpath
-com.android.tools:sdklib:30.2.0=classpath
-com.android:signflinger:7.2.0=classpath
-com.android:zipflinger:7.2.0=classpath
-com.fasterxml.jackson.core:jackson-annotations:2.11.1=classpath
-com.fasterxml.jackson.core:jackson-core:2.11.1=classpath
-com.fasterxml.jackson.core:jackson-databind:2.11.1=classpath
-com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.11.1=classpath
-com.fasterxml.jackson.module:jackson-module-jaxb-annotations:2.11.1=classpath
-com.fasterxml.jackson.module:jackson-module-kotlin:2.11.1=classpath
-com.fasterxml.woodstox:woodstox-core:6.2.1=classpath
+com.android.tools.ddms:ddmlib:30.3.0=classpath
+com.android.tools.layoutlib:layoutlib-api:30.3.0=classpath
+com.android.tools.lint:lint-model:30.3.0=classpath
+com.android.tools.lint:lint-typedef-remover:30.3.0=classpath
+com.android.tools.utp:android-device-provider-ddmlib-proto:30.3.0=classpath
+com.android.tools.utp:android-device-provider-gradle-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-host-additional-test-output-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-host-coverage-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-host-retention-proto:30.3.0=classpath
+com.android.tools.utp:android-test-plugin-result-listener-gradle-proto:30.3.0=classpath
+com.android.tools:annotations:30.3.0=classpath
+com.android.tools:common:30.3.0=classpath
+com.android.tools:dvlib:30.3.0=classpath
+com.android.tools:repository:30.3.0=classpath
+com.android.tools:sdk-common:30.3.0=classpath
+com.android.tools:sdklib:30.3.0=classpath
+com.android:signflinger:7.3.0=classpath
+com.android:zipflinger:7.3.0=classpath
com.github.gundy:semver4j:0.16.4=classpath
com.google.android:annotations:4.1.1.4=classpath
-com.google.api.grpc:proto-google-common-protos:1.12.0=classpath
+com.google.api.grpc:proto-google-common-protos:2.0.1=classpath
com.google.auto.value:auto-value-annotations:1.6.2=classpath
com.google.code.findbugs:jsr305:3.0.2=classpath
-com.google.code.gson:gson:2.8.6=classpath
+com.google.code.gson:gson:2.8.9=classpath
com.google.crypto.tink:tink:1.3.0-rc2=classpath
com.google.dagger:dagger:2.28.3=classpath
-com.google.errorprone:error_prone_annotations:2.3.4=classpath
+com.google.errorprone:error_prone_annotations:2.4.0=classpath
com.google.flatbuffers:flatbuffers-java:1.12.0=classpath
com.google.guava:failureaccess:1.0.1=classpath
com.google.guava:guava:30.1-jre=classpath
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=classpath
com.google.j2objc:j2objc-annotations:1.3=classpath
com.google.jimfs:jimfs:1.1=classpath
-com.google.protobuf:protobuf-java-util:3.10.0=classpath
-com.google.protobuf:protobuf-java:3.10.0=classpath
+com.google.protobuf:protobuf-java-util:3.17.2=classpath
+com.google.protobuf:protobuf-java:3.17.2=classpath
com.google.testing.platform:core-proto:0.0.8-alpha07=classpath
com.googlecode.json-simple:json-simple:1.1=classpath
com.googlecode.juniversalchardet:juniversalchardet:1.0.3=classpath
@@ -76,80 +69,76 @@
commons-io:commons-io:2.4=classpath
commons-logging:commons-logging:1.2=classpath
de.undercouch:gradle-download-task:4.1.1=classpath
-io.grpc:grpc-api:1.21.1=classpath
-io.grpc:grpc-context:1.21.1=classpath
-io.grpc:grpc-core:1.21.1=classpath
-io.grpc:grpc-netty:1.21.1=classpath
-io.grpc:grpc-protobuf-lite:1.21.1=classpath
-io.grpc:grpc-protobuf:1.21.1=classpath
-io.grpc:grpc-stub:1.21.1=classpath
-io.netty:netty-buffer:4.1.34.Final=classpath
-io.netty:netty-codec-http2:4.1.34.Final=classpath
-io.netty:netty-codec-http:4.1.34.Final=classpath
-io.netty:netty-codec-socks:4.1.34.Final=classpath
-io.netty:netty-codec:4.1.34.Final=classpath
-io.netty:netty-common:4.1.34.Final=classpath
-io.netty:netty-handler-proxy:4.1.34.Final=classpath
-io.netty:netty-handler:4.1.34.Final=classpath
-io.netty:netty-resolver:4.1.34.Final=classpath
-io.netty:netty-transport:4.1.34.Final=classpath
-io.opencensus:opencensus-api:0.21.0=classpath
-io.opencensus:opencensus-contrib-grpc-metrics:0.21.0=classpath
+io.grpc:grpc-api:1.39.0=classpath
+io.grpc:grpc-context:1.39.0=classpath
+io.grpc:grpc-core:1.39.0=classpath
+io.grpc:grpc-netty:1.39.0=classpath
+io.grpc:grpc-protobuf-lite:1.39.0=classpath
+io.grpc:grpc-protobuf:1.39.0=classpath
+io.grpc:grpc-stub:1.39.0=classpath
+io.netty:netty-buffer:4.1.52.Final=classpath
+io.netty:netty-codec-http2:4.1.52.Final=classpath
+io.netty:netty-codec-http:4.1.52.Final=classpath
+io.netty:netty-codec-socks:4.1.52.Final=classpath
+io.netty:netty-codec:4.1.52.Final=classpath
+io.netty:netty-common:4.1.52.Final=classpath
+io.netty:netty-handler-proxy:4.1.52.Final=classpath
+io.netty:netty-handler:4.1.52.Final=classpath
+io.netty:netty-resolver:4.1.52.Final=classpath
+io.netty:netty-transport:4.1.52.Final=classpath
+io.perfmark:perfmark-api:0.23.0=classpath
it.unimi.dsi:fastutil:8.4.0=classpath
jakarta.activation:jakarta.activation-api:1.2.1=classpath
jakarta.xml.bind:jakarta.xml.bind-api:2.3.2=classpath
+javax.annotation:javax.annotation-api:1.3.2=classpath
javax.inject:javax.inject:1=classpath
net.java.dev.jna:jna-platform:5.6.0=classpath
net.java.dev.jna:jna:5.6.0=classpath
net.sf.jopt-simple:jopt-simple:4.9=classpath
net.sf.kxml:kxml2:2.3.0=classpath
org.apache.commons:commons-compress:1.20=classpath
-org.apache.httpcomponents:httpclient:4.5.9=classpath
-org.apache.httpcomponents:httpcore:4.4.11=classpath
+org.apache.httpcomponents:httpclient:4.5.13=classpath
+org.apache.httpcomponents:httpcore:4.4.13=classpath
org.apache.httpcomponents:httpmime:4.5.6=classpath
org.bitbucket.b_c:jose4j:0.7.0=classpath
-org.bouncycastle:bcpkix-jdk15on:1.56=classpath
-org.bouncycastle:bcprov-jdk15on:1.56=classpath
+org.bouncycastle:bcpkix-jdk15on:1.67=classpath
+org.bouncycastle:bcprov-jdk15on:1.67=classpath
org.checkerframework:checker-qual:3.5.0=classpath
-org.codehaus.mojo:animal-sniffer-annotations:1.17=classpath
-org.codehaus.woodstox:stax2-api:4.2.1=classpath
+org.codehaus.mojo:animal-sniffer-annotations:1.19=classpath
org.glassfish.jaxb:jaxb-runtime:2.3.2=classpath
org.glassfish.jaxb:txw2:2.3.2=classpath
org.jdom:jdom2:2.0.6=classpath
-org.jetbrains.dokka:dokka-core:1.4.32=classpath
-org.jetbrains.intellij.deps:trove4j:1.0.20181211=classpath
-org.jetbrains.kotlin:kotlin-android-extensions:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-annotation-processing-gradle:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-build-common:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-compiler-embeddable:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-compiler-runner:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-daemon-client:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-daemon-embeddable:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-native-utils:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-project-model:1.5.31=classpath
+org.jetbrains.intellij.deps:trove4j:1.0.20200330=classpath
+org.jetbrains.kotlin:kotlin-android-extensions:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-annotation-processing-gradle:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-build-common:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-compiler-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-compiler-runner:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-daemon-client:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-daemon-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin-idea:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-native-utils:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-project-model:1.7.10=classpath
org.jetbrains.kotlin:kotlin-reflect:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-scripting-common:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-scripting-jvm:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-scripting-common:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-scripting-jvm:1.7.10=classpath
org.jetbrains.kotlin:kotlin-stdlib-common:1.5.31=classpath
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.5.31=classpath
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.31=classpath
org.jetbrains.kotlin:kotlin-stdlib:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-tooling-metadata:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-util-io:1.5.31=classpath
-org.jetbrains.kotlin:kotlin-util-klib:1.5.31=classpath
+org.jetbrains.kotlin:kotlin-tooling-core:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-tooling-metadata:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-util-io:1.7.10=classpath
+org.jetbrains.kotlin:kotlin-util-klib:1.7.10=classpath
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.0=classpath
-org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0=classpath
org.jetbrains:annotations:13.0=classpath
-org.jetbrains:markdown-jvm:0.2.1=classpath
-org.jetbrains:markdown:0.2.1=classpath
org.json:json:20180813=classpath
-org.jsoup:jsoup:1.13.1=classpath
org.jvnet.staxex:stax-ex:1.8.1=classpath
org.ow2.asm:asm-analysis:9.1=classpath
org.ow2.asm:asm-commons:9.1=classpath
diff --git a/dev/integration_tests/ui/android/gradle/wrapper/gradle-wrapper.properties b/dev/integration_tests/ui/android/gradle/wrapper/gradle-wrapper.properties
index f338a88..cb24abd 100644
--- a/dev/integration_tests/ui/android/gradle/wrapper/gradle-wrapper.properties
+++ b/dev/integration_tests/ui/android/gradle/wrapper/gradle-wrapper.properties
@@ -2,4 +2,4 @@
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip
diff --git a/dev/integration_tests/ui/android/settings.gradle b/dev/integration_tests/ui/android/settings.gradle
index 03ae72d..a020595 100644
--- a/dev/integration_tests/ui/android/settings.gradle
+++ b/dev/integration_tests/ui/android/settings.gradle
@@ -8,8 +8,6 @@
include ':app'
-enableFeaturePreview('ONE_LOCKFILE_PER_PROJECT')
-
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()
diff --git a/dev/integration_tests/ui/ios/Runner/Info.plist b/dev/integration_tests/ui/ios/Runner/Info.plist
index b698021..48648e5 100644
--- a/dev/integration_tests/ui/ios/Runner/Info.plist
+++ b/dev/integration_tests/ui/ios/Runner/Info.plist
@@ -39,8 +39,6 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
- <key>UIViewControllerBasedStatusBarAppearance</key>
- <false/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
diff --git a/dev/integration_tests/ui/linux/flutter/generated_plugins.cmake b/dev/integration_tests/ui/linux/flutter/generated_plugins.cmake
deleted file mode 100644
index 2e1de87..0000000
--- a/dev/integration_tests/ui/linux/flutter/generated_plugins.cmake
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Generated file, do not edit.
-#
-
-list(APPEND FLUTTER_PLUGIN_LIST
-)
-
-list(APPEND FLUTTER_FFI_PLUGIN_LIST
-)
-
-set(PLUGIN_BUNDLED_LIBRARIES)
-
-foreach(plugin ${FLUTTER_PLUGIN_LIST})
- add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin})
- target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
- list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
- list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
-endforeach(plugin)
-
-foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
- add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin})
- list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
-endforeach(ffi_plugin)
diff --git a/dev/integration_tests/ui/pubspec.yaml b/dev/integration_tests/ui/pubspec.yaml
index 64662dc..8410214 100644
--- a/dev/integration_tests/ui/pubspec.yaml
+++ b/dev/integration_tests/ui/pubspec.yaml
@@ -11,10 +11,10 @@
sdk: flutter
integration_test:
sdk: flutter
- test: 1.24.3
+ test: 1.24.4
- _fe_analyzer_shared: 61.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- analyzer: 5.13.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ _fe_analyzer_shared: 62.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ analyzer: 6.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
args: 2.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
async: 2.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -23,6 +23,7 @@
convert: 3.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
coverage: 1.6.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
crypto: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ dart_internal: 0.2.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
file: 6.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
frontend_server_client: 3.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
glob: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -47,16 +48,17 @@
source_map_stack_trace: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_maps: 0.10.12 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
sync_http: 0.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_core: 0.5.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_core: 0.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- vm_service: 11.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ vm_service: 11.7.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -65,7 +67,7 @@
dev_dependencies:
flutter_test:
sdk: flutter
- test_api: 0.6.0
+ test_api: 0.6.1
clock: 1.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
fake_async: 1.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -75,4 +77,4 @@
assets:
- assets/foo.png
-# PUBSPEC CHECKSUM: db36
+# PUBSPEC CHECKSUM: be20
diff --git a/dev/integration_tests/ui/windows/flutter/generated_plugins.cmake b/dev/integration_tests/ui/windows/flutter/generated_plugins.cmake
deleted file mode 100644
index b93c4c3..0000000
--- a/dev/integration_tests/ui/windows/flutter/generated_plugins.cmake
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Generated file, do not edit.
-#
-
-list(APPEND FLUTTER_PLUGIN_LIST
-)
-
-list(APPEND FLUTTER_FFI_PLUGIN_LIST
-)
-
-set(PLUGIN_BUNDLED_LIBRARIES)
-
-foreach(plugin ${FLUTTER_PLUGIN_LIST})
- add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin})
- target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
- list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
- list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
-endforeach(plugin)
-
-foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
- add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin})
- list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
-endforeach(ffi_plugin)
diff --git a/dev/integration_tests/web/pubspec.yaml b/dev/integration_tests/web/pubspec.yaml
index eaeb409..71008e7 100644
--- a/dev/integration_tests/web/pubspec.yaml
+++ b/dev/integration_tests/web/pubspec.yaml
@@ -16,9 +16,9 @@
characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
collection: 1.17.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.9.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
-# PUBSPEC CHECKSUM: 3e9c
+# PUBSPEC CHECKSUM: a9c0
diff --git a/dev/integration_tests/web_compile_tests/pubspec.yaml b/dev/integration_tests/web_compile_tests/pubspec.yaml
index 6eed3c4..9dc5925 100644
--- a/dev/integration_tests/web_compile_tests/pubspec.yaml
+++ b/dev/integration_tests/web_compile_tests/pubspec.yaml
@@ -8,9 +8,9 @@
characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
collection: 1.17.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.9.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
-# PUBSPEC CHECKSUM: 3e9c
+# PUBSPEC CHECKSUM: a9c0
diff --git a/dev/integration_tests/web_e2e_tests/pubspec.yaml b/dev/integration_tests/web_e2e_tests/pubspec.yaml
index 9a4c06e..e736b7f 100644
--- a/dev/integration_tests/web_e2e_tests/pubspec.yaml
+++ b/dev/integration_tests/web_e2e_tests/pubspec.yaml
@@ -29,39 +29,41 @@
collection: 1.17.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
fake_async: 1.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
file: 6.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
matcher: 0.12.16 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.9.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path: 1.8.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
sync_http: 0.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- vm_service: 11.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ vm_service: 11.7.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
flutter_goldens:
sdk: flutter
http: 0.13.6
- test: 1.24.3
+ test: 1.24.4
- _fe_analyzer_shared: 61.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- analyzer: 5.13.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ _fe_analyzer_shared: 62.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ analyzer: 6.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
args: 2.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
convert: 3.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
coverage: 1.6.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
crypto: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ dart_internal: 0.2.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
frontend_server_client: 3.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
glob: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http_multi_server: 3.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http_parser: 4.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
io: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
logging: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
mime: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
node_preamble: 2.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -76,11 +78,11 @@
shelf_web_socket: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_map_stack_trace: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_maps: 0.10.12 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_core: 0.5.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_core: 0.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
-# PUBSPEC CHECKSUM: 1e1b
+# PUBSPEC CHECKSUM: 2405
diff --git a/dev/integration_tests/web_e2e_tests/test_driver/url_strategy_integration.dart b/dev/integration_tests/web_e2e_tests/test_driver/url_strategy_integration.dart
index 6122172..bba6a6d 100644
--- a/dev/integration_tests/web_e2e_tests/test_driver/url_strategy_integration.dart
+++ b/dev/integration_tests/web_e2e_tests/test_driver/url_strategy_integration.dart
@@ -46,11 +46,6 @@
/// It keeps a list of history entries and event listeners in memory and
/// manipulates them in order to achieve the desired functionality.
class TestUrlStrategy extends UrlStrategy {
- /// Creates a instance of [TestUrlStrategy] with an empty string as the
- /// path.
- factory TestUrlStrategy() =>
- TestUrlStrategy.fromEntry(const TestHistoryEntry(null, null, ''));
-
/// Creates an instance of [TestUrlStrategy] and populates it with a list
/// that has [initialEntry] as the only item.
TestUrlStrategy.fromEntry(TestHistoryEntry initialEntry)
@@ -64,8 +59,6 @@
dynamic getState() => currentEntry.state;
int _currentEntryIndex;
- int get currentEntryIndex => _currentEntryIndex;
-
final List<TestHistoryEntry> history;
TestHistoryEntry get currentEntry {
@@ -105,16 +98,6 @@
currentEntry = TestHistoryEntry(state, title, url);
}
- /// This simulates the case where a user types in a url manually. It causes
- /// a new state to be pushed, and all event listeners will be invoked.
- Future<void> simulateUserTypingUrl(String url) {
- assert(withinAppHistory);
- return _nextEventLoop(() {
- pushState(null, '', url);
- _firePopStateEvent();
- });
- }
-
@override
Future<void> go(int count) {
assert(withinAppHistory);
diff --git a/dev/integration_tests/wide_gamut_test/ios/Runner/Info.plist b/dev/integration_tests/wide_gamut_test/ios/Runner/Info.plist
index 6317e5e..7ade06a 100644
--- a/dev/integration_tests/wide_gamut_test/ios/Runner/Info.plist
+++ b/dev/integration_tests/wide_gamut_test/ios/Runner/Info.plist
@@ -41,8 +41,6 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
- <key>UIViewControllerBasedStatusBarAppearance</key>
- <false/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
diff --git a/dev/integration_tests/wide_gamut_test/pubspec.yaml b/dev/integration_tests/wide_gamut_test/pubspec.yaml
index 576d72d..aa93540 100644
--- a/dev/integration_tests/wide_gamut_test/pubspec.yaml
+++ b/dev/integration_tests/wide_gamut_test/pubspec.yaml
@@ -13,10 +13,10 @@
characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
collection: 1.17.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.9.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
flutter_test:
@@ -31,14 +31,14 @@
matcher: 0.12.16 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path: 1.8.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- vm_service: 11.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ vm_service: 11.7.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
flutter:
uses-material-design: true
-# PUBSPEC CHECKSUM: 39d4
+# PUBSPEC CHECKSUM: 07fe
diff --git a/dev/integration_tests/windows_startup_test/pubspec.yaml b/dev/integration_tests/windows_startup_test/pubspec.yaml
index 6bdcd99..2c10a28 100644
--- a/dev/integration_tests/windows_startup_test/pubspec.yaml
+++ b/dev/integration_tests/windows_startup_test/pubspec.yaml
@@ -9,10 +9,10 @@
sdk: flutter
flutter_driver:
sdk: flutter
- test: 1.24.3
+ test: 1.24.4
- _fe_analyzer_shared: 61.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- analyzer: 5.13.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ _fe_analyzer_shared: 62.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ analyzer: 6.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
args: 2.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
async: 2.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -21,6 +21,7 @@
convert: 3.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
coverage: 1.6.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
crypto: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ dart_internal: 0.2.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
file: 6.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
frontend_server_client: 3.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
glob: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -45,20 +46,21 @@
source_map_stack_trace: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_maps: 0.10.12 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
sync_http: 0.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_core: 0.5.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_core: 0.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- vm_service: 11.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ vm_service: 11.7.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
-# PUBSPEC CHECKSUM: a079
+# PUBSPEC CHECKSUM: c363
diff --git a/dev/integration_tests/windows_startup_test/windows/flutter/generated_plugins.cmake b/dev/integration_tests/windows_startup_test/windows/flutter/generated_plugins.cmake
deleted file mode 100644
index b93c4c3..0000000
--- a/dev/integration_tests/windows_startup_test/windows/flutter/generated_plugins.cmake
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Generated file, do not edit.
-#
-
-list(APPEND FLUTTER_PLUGIN_LIST
-)
-
-list(APPEND FLUTTER_FFI_PLUGIN_LIST
-)
-
-set(PLUGIN_BUNDLED_LIBRARIES)
-
-foreach(plugin ${FLUTTER_PLUGIN_LIST})
- add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin})
- target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
- list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
- list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
-endforeach(plugin)
-
-foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
- add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin})
- list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
-endforeach(ffi_plugin)
diff --git a/dev/manual_tests/ios/Runner/Info.plist b/dev/manual_tests/ios/Runner/Info.plist
index 65bdf88..43fe8f0 100644
--- a/dev/manual_tests/ios/Runner/Info.plist
+++ b/dev/manual_tests/ios/Runner/Info.plist
@@ -41,8 +41,6 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
- <key>UIViewControllerBasedStatusBarAppearance</key>
- <true/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
diff --git a/dev/manual_tests/lib/actions.dart b/dev/manual_tests/lib/actions.dart
index ced4624..0e494d1 100644
--- a/dev/manual_tests/lib/actions.dart
+++ b/dev/manual_tests/lib/actions.dart
@@ -56,13 +56,6 @@
/// An [ActionDispatcher] subclass that manages the invocation of undoable
/// actions.
class UndoableActionDispatcher extends ActionDispatcher implements Listenable {
- /// Constructs a new [UndoableActionDispatcher].
- ///
- /// The [maxUndoLevels] argument must not be null.
- UndoableActionDispatcher({
- int maxUndoLevels = _defaultMaxUndoLevels,
- }) : _maxUndoLevels = maxUndoLevels;
-
// A stack of actions that have been performed. The most recent action
// performed is at the end of the list.
final DoubleLinkedQueue<Memento> _completedActions = DoubleLinkedQueue<Memento>();
@@ -70,19 +63,12 @@
// at the end of the list.
final List<Memento> _undoneActions = <Memento>[];
- static const int _defaultMaxUndoLevels = 1000;
-
/// The maximum number of undo levels allowed.
///
/// If this value is set to a value smaller than the number of completed
/// actions, then the stack of completed actions is truncated to only include
/// the last [maxUndoLevels] actions.
- int get maxUndoLevels => _maxUndoLevels;
- int _maxUndoLevels;
- set maxUndoLevels(int value) {
- _maxUndoLevels = value;
- _pruneActions();
- }
+ int get maxUndoLevels => 1000;
final Set<VoidCallback> _listeners = <VoidCallback>{};
@@ -121,7 +107,7 @@
// Enforces undo level limit.
void _pruneActions() {
- while (_completedActions.length > _maxUndoLevels) {
+ while (_completedActions.length > maxUndoLevels) {
_completedActions.removeFirst();
}
}
@@ -237,26 +223,12 @@
}
/// An action that can be undone.
-abstract class UndoableAction<T extends Intent> extends Action<T> {
- /// The [Intent] this action was originally invoked with.
- Intent? get invocationIntent => _invocationTag;
- Intent? _invocationTag;
-
- @protected
- set invocationIntent(Intent? value) => _invocationTag = value;
-
- @override
- @mustCallSuper
- void invoke(T intent) {
- invocationIntent = intent;
- }
-}
+abstract class UndoableAction<T extends Intent> extends Action<T> { }
class UndoableFocusActionBase<T extends Intent> extends UndoableAction<T> {
@override
@mustCallSuper
Memento invoke(T intent) {
- super.invoke(intent);
final FocusNode? previousFocus = primaryFocus;
return Memento(name: previousFocus!.debugLabel!, undo: () {
previousFocus.requestFocus();
@@ -295,8 +267,6 @@
}
class UndoableDirectionalFocusAction extends UndoableFocusActionBase<DirectionalFocusIntent> {
- TraversalDirection? direction;
-
@override
Memento invoke(DirectionalFocusIntent intent) {
final Memento memento = super.invoke(intent);
diff --git a/dev/manual_tests/lib/density.dart b/dev/manual_tests/lib/density.dart
index 696d987..02e252e 100644
--- a/dev/manual_tests/lib/density.dart
+++ b/dev/manual_tests/lib/density.dart
@@ -30,15 +30,13 @@
Widget build(BuildContext context) {
return const MaterialApp(
title: _title,
- home: MyHomePage(title: _title),
+ home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
- const MyHomePage({super.key, required this.title});
-
- final String title;
+ const MyHomePage({super.key});
@override
State<MyHomePage> createState() => _MyHomePageState();
@@ -92,12 +90,6 @@
bool get longText => _longText;
bool _longText = false;
- set longText(bool longText) {
- if (longText != _longText) {
- _longText = longText;
- notifyListeners();
- }
- }
void reset() {
final OptionModel defaultModel = OptionModel();
diff --git a/dev/manual_tests/lib/menu_anchor.dart b/dev/manual_tests/lib/menu_anchor.dart
index 7b3e0db..b6f98d3 100644
--- a/dev/manual_tests/lib/menu_anchor.dart
+++ b/dev/manual_tests/lib/menu_anchor.dart
@@ -778,9 +778,4 @@
final String acceleratorLabel;
// Strip the accelerator markers.
String get label => MenuAcceleratorLabel.stripAcceleratorMarkers(acceleratorLabel);
- int get acceleratorIndex {
- int index = -1;
- MenuAcceleratorLabel.stripAcceleratorMarkers(acceleratorLabel, setIndex: (int i) => index = i);
- return index;
- }
}
diff --git a/dev/manual_tests/linux/flutter/generated_plugin_registrant.cc b/dev/manual_tests/linux/flutter/generated_plugin_registrant.cc
deleted file mode 100644
index e71a16d..0000000
--- a/dev/manual_tests/linux/flutter/generated_plugin_registrant.cc
+++ /dev/null
@@ -1,11 +0,0 @@
-//
-// Generated file. Do not edit.
-//
-
-// clang-format off
-
-#include "generated_plugin_registrant.h"
-
-
-void fl_register_plugins(FlPluginRegistry* registry) {
-}
diff --git a/dev/manual_tests/linux/flutter/generated_plugin_registrant.h b/dev/manual_tests/linux/flutter/generated_plugin_registrant.h
deleted file mode 100644
index e0f0a47..0000000
--- a/dev/manual_tests/linux/flutter/generated_plugin_registrant.h
+++ /dev/null
@@ -1,15 +0,0 @@
-//
-// Generated file. Do not edit.
-//
-
-// clang-format off
-
-#ifndef GENERATED_PLUGIN_REGISTRANT_
-#define GENERATED_PLUGIN_REGISTRANT_
-
-#include <flutter_linux/flutter_linux.h>
-
-// Registers Flutter plugins.
-void fl_register_plugins(FlPluginRegistry* registry);
-
-#endif // GENERATED_PLUGIN_REGISTRANT_
diff --git a/dev/manual_tests/linux/flutter/generated_plugins.cmake b/dev/manual_tests/linux/flutter/generated_plugins.cmake
deleted file mode 100644
index 2e1de87..0000000
--- a/dev/manual_tests/linux/flutter/generated_plugins.cmake
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Generated file, do not edit.
-#
-
-list(APPEND FLUTTER_PLUGIN_LIST
-)
-
-list(APPEND FLUTTER_FFI_PLUGIN_LIST
-)
-
-set(PLUGIN_BUNDLED_LIBRARIES)
-
-foreach(plugin ${FLUTTER_PLUGIN_LIST})
- add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin})
- target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
- list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
- list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
-endforeach(plugin)
-
-foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
- add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin})
- list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
-endforeach(ffi_plugin)
diff --git a/dev/manual_tests/pubspec.yaml b/dev/manual_tests/pubspec.yaml
index 671f00a..c69dd93 100644
--- a/dev/manual_tests/pubspec.yaml
+++ b/dev/manual_tests/pubspec.yaml
@@ -9,10 +9,10 @@
characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
collection: 1.17.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.9.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
flutter_test:
@@ -25,13 +25,13 @@
matcher: 0.12.16 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path: 1.8.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
flutter:
uses-material-design: true
-# PUBSPEC CHECKSUM: d91e
+# PUBSPEC CHECKSUM: 7f45
diff --git a/dev/manual_tests/windows/flutter/generated_plugin_registrant.cc b/dev/manual_tests/windows/flutter/generated_plugin_registrant.cc
deleted file mode 100644
index 8b6d468..0000000
--- a/dev/manual_tests/windows/flutter/generated_plugin_registrant.cc
+++ /dev/null
@@ -1,11 +0,0 @@
-//
-// Generated file. Do not edit.
-//
-
-// clang-format off
-
-#include "generated_plugin_registrant.h"
-
-
-void RegisterPlugins(flutter::PluginRegistry* registry) {
-}
diff --git a/dev/manual_tests/windows/flutter/generated_plugin_registrant.h b/dev/manual_tests/windows/flutter/generated_plugin_registrant.h
deleted file mode 100644
index dc139d8..0000000
--- a/dev/manual_tests/windows/flutter/generated_plugin_registrant.h
+++ /dev/null
@@ -1,15 +0,0 @@
-//
-// Generated file. Do not edit.
-//
-
-// clang-format off
-
-#ifndef GENERATED_PLUGIN_REGISTRANT_
-#define GENERATED_PLUGIN_REGISTRANT_
-
-#include <flutter/plugin_registry.h>
-
-// Registers Flutter plugins.
-void RegisterPlugins(flutter::PluginRegistry* registry);
-
-#endif // GENERATED_PLUGIN_REGISTRANT_
diff --git a/dev/manual_tests/windows/flutter/generated_plugins.cmake b/dev/manual_tests/windows/flutter/generated_plugins.cmake
deleted file mode 100644
index b93c4c3..0000000
--- a/dev/manual_tests/windows/flutter/generated_plugins.cmake
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Generated file, do not edit.
-#
-
-list(APPEND FLUTTER_PLUGIN_LIST
-)
-
-list(APPEND FLUTTER_FFI_PLUGIN_LIST
-)
-
-set(PLUGIN_BUNDLED_LIBRARIES)
-
-foreach(plugin ${FLUTTER_PLUGIN_LIST})
- add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin})
- target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
- list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
- list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
-endforeach(plugin)
-
-foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
- add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin})
- list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
-endforeach(ffi_plugin)
diff --git a/dev/tools/examples_smoke_test.dart b/dev/tools/examples_smoke_test.dart
index 732eb31..f4877ff 100644
--- a/dev/tools/examples_smoke_test.dart
+++ b/dev/tools/examples_smoke_test.dart
@@ -81,13 +81,12 @@
// A class to hold information related to an example, used to generate names
// from for the tests.
class ExampleInfo {
- ExampleInfo(this.file, Directory examplesLibDir)
+ ExampleInfo(File file, Directory examplesLibDir)
: importPath = _getImportPath(file, examplesLibDir),
importName = '' {
importName = importPath.replaceAll(RegExp(r'\.dart$'), '').replaceAll(RegExp(r'\W'), '_');
}
- final File file;
final String importPath;
String importName;
diff --git a/dev/tools/gen_defaults/generated/used_tokens.csv b/dev/tools/gen_defaults/generated/used_tokens.csv
index 6fb5c5a..fd5cf2e 100644
--- a/dev/tools/gen_defaults/generated/used_tokens.csv
+++ b/dev/tools/gen_defaults/generated/used_tokens.csv
@@ -423,6 +423,7 @@
md.comp.navigation-drawer.active-indicator.height,
md.comp.navigation-drawer.active-indicator.shape,
md.comp.navigation-drawer.active-indicator.width,
+md.comp.navigation-drawer.active.icon.color,
md.comp.navigation-drawer.active.label-text.color,
md.comp.navigation-drawer.container.color,
md.comp.navigation-drawer.container.surface-tint-layer.color,
diff --git a/dev/tools/gen_defaults/lib/action_chip_template.dart b/dev/tools/gen_defaults/lib/action_chip_template.dart
index 4d67294..54027c1 100644
--- a/dev/tools/gen_defaults/lib/action_chip_template.dart
+++ b/dev/tools/gen_defaults/lib/action_chip_template.dart
@@ -41,7 +41,15 @@
TextStyle? get labelStyle => ${textStyle("$tokenGroup.label-text")};
@override
- Color? get backgroundColor => ${componentColor("$tokenGroup$flatVariant.container")};
+ MaterialStateProperty<Color?>? get color =>
+ MaterialStateProperty.resolveWith((Set<MaterialState> states) {
+ if (states.contains(MaterialState.disabled)) {
+ return _chipVariant == _ChipVariant.flat
+ ? ${componentColor("$tokenGroup$flatVariant.disabled.container")}
+ : ${componentColor("$tokenGroup$elevatedVariant.disabled.container")};
+ }
+ return ${componentColor("$tokenGroup$flatVariant.container")};
+ });
@override
Color? get shadowColor => _chipVariant == _ChipVariant.flat
@@ -52,17 +60,9 @@
Color? get surfaceTintColor => ${colorOrTransparent("$tokenGroup.container.surface-tint-layer.color")};
@override
- Color? get selectedColor => ${componentColor("$tokenGroup$flatVariant.selected.container")};
-
- @override
Color? get checkmarkColor => ${color("$tokenGroup.with-icon.selected.icon.color")};
@override
- Color? get disabledColor => _chipVariant == _ChipVariant.flat
- ? ${componentColor("$tokenGroup$flatVariant.disabled.container")}
- : ${componentColor("$tokenGroup$elevatedVariant.disabled.container")};
-
- @override
Color? get deleteIconColor => ${color("$tokenGroup.with-icon.selected.icon.color")};
@override
diff --git a/dev/tools/gen_defaults/lib/chip_template.dart b/dev/tools/gen_defaults/lib/chip_template.dart
index 016bd40..8d9c05b 100644
--- a/dev/tools/gen_defaults/lib/chip_template.dart
+++ b/dev/tools/gen_defaults/lib/chip_template.dart
@@ -32,7 +32,7 @@
TextStyle? get labelStyle => ${textStyle("$tokenGroup.label-text")};
@override
- Color? get backgroundColor => ${componentColor("$tokenGroup$variant.container")};
+ MaterialStateProperty<Color?>? get color => null; // Subclasses override this getter
@override
Color? get shadowColor => ${colorOrTransparent("$tokenGroup.container.shadow-color")};
@@ -41,15 +41,9 @@
Color? get surfaceTintColor => ${colorOrTransparent("$tokenGroup.container.surface-tint-layer.color")};
@override
- Color? get selectedColor => ${componentColor("$tokenGroup$variant.selected.container")};
-
- @override
Color? get checkmarkColor => ${color("$tokenGroup.with-icon.selected.icon.color")};
@override
- Color? get disabledColor => ${componentColor("$tokenGroup$variant.disabled.container")};
-
- @override
Color? get deleteIconColor => ${color("$tokenGroup.with-icon.selected.icon.color")};
@override
diff --git a/dev/tools/gen_defaults/lib/filter_chip_template.dart b/dev/tools/gen_defaults/lib/filter_chip_template.dart
index 54119c5..6609613 100644
--- a/dev/tools/gen_defaults/lib/filter_chip_template.dart
+++ b/dev/tools/gen_defaults/lib/filter_chip_template.dart
@@ -46,7 +46,27 @@
TextStyle? get labelStyle => ${textStyle("$tokenGroup.label-text")};
@override
- Color? get backgroundColor => ${componentColor("$tokenGroup$flatVariant.container")};
+ MaterialStateProperty<Color?>? get color =>
+ MaterialStateProperty.resolveWith((Set<MaterialState> states) {
+ if (states.contains(MaterialState.selected) && states.contains(MaterialState.disabled)) {
+ return _chipVariant == _ChipVariant.flat
+ ? ${componentColor("$tokenGroup$flatVariant.disabled.selected.container")}
+ : ${componentColor("$tokenGroup$elevatedVariant.disabled.container")};
+ }
+ if (states.contains(MaterialState.disabled)) {
+ return _chipVariant == _ChipVariant.flat
+ ? ${componentColor("$tokenGroup$flatVariant.disabled.unselected.container")}
+ : ${componentColor("$tokenGroup$elevatedVariant.disabled.container")};
+ }
+ if (states.contains(MaterialState.selected)) {
+ return _chipVariant == _ChipVariant.flat
+ ? ${componentColor("$tokenGroup$flatVariant.selected.container")}
+ : ${componentColor("$tokenGroup$elevatedVariant.selected.container")};
+ }
+ return _chipVariant == _ChipVariant.flat
+ ? ${componentColor("$tokenGroup$flatVariant.container")}
+ : ${componentColor("$tokenGroup$elevatedVariant.container")};
+ });
@override
Color? get shadowColor => _chipVariant == _ChipVariant.flat
@@ -57,25 +77,9 @@
Color? get surfaceTintColor => ${colorOrTransparent("$tokenGroup.container.surface-tint-layer.color")};
@override
- Color? get selectedColor => _chipVariant == _ChipVariant.flat
- ? isEnabled
- ? ${componentColor("$tokenGroup$flatVariant.selected.container")}
- : ${componentColor("$tokenGroup$flatVariant.disabled.selected.container")}
- : isEnabled
- ? ${componentColor("$tokenGroup$elevatedVariant.selected.container")}
- : ${componentColor("$tokenGroup$elevatedVariant.disabled.container")};
-
- @override
Color? get checkmarkColor => ${color("$tokenGroup.with-leading-icon.selected.leading-icon.color")};
@override
- Color? get disabledColor => _chipVariant == _ChipVariant.flat
- ? isSelected
- ? ${componentColor("$tokenGroup$flatVariant.disabled.selected.container")}
- : ${componentColor("$tokenGroup$flatVariant.disabled.unselected.container")}
- : ${componentColor("$tokenGroup$elevatedVariant.disabled.container")};
-
- @override
Color? get deleteIconColor => ${color("$tokenGroup.with-trailing-icon.selected.trailing-icon.color")};
@override
diff --git a/dev/tools/gen_defaults/lib/input_chip_template.dart b/dev/tools/gen_defaults/lib/input_chip_template.dart
index 9226a73..245a171 100644
--- a/dev/tools/gen_defaults/lib/input_chip_template.dart
+++ b/dev/tools/gen_defaults/lib/input_chip_template.dart
@@ -33,7 +33,19 @@
TextStyle? get labelStyle => ${textStyle("$tokenGroup.label-text")};
@override
- Color? get backgroundColor => ${componentColor("$tokenGroup$variant.container")};
+ MaterialStateProperty<Color?>? get color =>
+ MaterialStateProperty.resolveWith((Set<MaterialState> states) {
+ if (states.contains(MaterialState.selected) && states.contains(MaterialState.disabled)) {
+ return ${componentColor("$tokenGroup$variant.disabled.selected.container")};
+ }
+ if (states.contains(MaterialState.disabled)) {
+ return ${componentColor("$tokenGroup$variant.disabled.container")};
+ }
+ if (states.contains(MaterialState.selected)) {
+ return ${componentColor("$tokenGroup$variant.selected.container")};
+ }
+ return ${componentColor("$tokenGroup$variant.container")};
+ });
@override
Color? get shadowColor => ${colorOrTransparent("$tokenGroup.container.shadow-color")};
@@ -42,17 +54,9 @@
Color? get surfaceTintColor => ${colorOrTransparent("$tokenGroup.container.surface-tint-layer.color")};
@override
- Color? get selectedColor => isEnabled
- ? ${componentColor("$tokenGroup$variant.selected.container")}
- : ${componentColor("$tokenGroup$variant.disabled.selected.container")};
-
- @override
Color? get checkmarkColor => ${color("$tokenGroup.with-icon.selected.icon.color")};
@override
- Color? get disabledColor => ${componentColor("$tokenGroup$variant.disabled.container")};
-
- @override
Color? get deleteIconColor => ${color("$tokenGroup.with-trailing-icon.selected.trailing-icon.color")};
@override
diff --git a/dev/tools/gen_defaults/lib/navigation_drawer_template.dart b/dev/tools/gen_defaults/lib/navigation_drawer_template.dart
index f5079d9..5371822 100644
--- a/dev/tools/gen_defaults/lib/navigation_drawer_template.dart
+++ b/dev/tools/gen_defaults/lib/navigation_drawer_template.dart
@@ -43,7 +43,7 @@
return IconThemeData(
size: ${getToken("md.comp.navigation-drawer.icon.size")},
color: states.contains(MaterialState.selected)
- ? ${componentColor("md.comp.navigation-drawer.active.icon.")}
+ ? ${componentColor("md.comp.navigation-drawer.active.icon")}
: ${componentColor("md.comp.navigation-drawer.inactive.icon")},
);
});
diff --git a/dev/tools/gen_defaults/pubspec.yaml b/dev/tools/gen_defaults/pubspec.yaml
index dd20738..3222e85 100644
--- a/dev/tools/gen_defaults/pubspec.yaml
+++ b/dev/tools/gen_defaults/pubspec.yaml
@@ -10,16 +10,17 @@
dev_dependencies:
path: 1.8.3
- test: 1.24.3
+ test: 1.24.4
- _fe_analyzer_shared: 61.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- analyzer: 5.13.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ _fe_analyzer_shared: 62.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ analyzer: 6.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
async: 2.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
collection: 1.17.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
convert: 3.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
coverage: 1.6.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
crypto: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ dart_internal: 0.2.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
file: 6.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
frontend_server_client: 3.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
glob: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -42,17 +43,17 @@
source_map_stack_trace: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_maps: 0.10.12 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_core: 0.5.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_core: 0.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- vm_service: 11.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ vm_service: 11.7.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
-# PUBSPEC CHECKSUM: 8c77
+# PUBSPEC CHECKSUM: 940b
diff --git a/dev/tools/gen_keycodes/pubspec.yaml b/dev/tools/gen_keycodes/pubspec.yaml
index 55d1042..53abe32 100644
--- a/dev/tools/gen_keycodes/pubspec.yaml
+++ b/dev/tools/gen_keycodes/pubspec.yaml
@@ -20,15 +20,16 @@
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
- test: 1.24.3
- test_api: 0.6.0
+ test: 1.24.4
+ test_api: 0.6.1
- _fe_analyzer_shared: 61.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- analyzer: 5.13.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ _fe_analyzer_shared: 62.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ analyzer: 6.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
convert: 3.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
coverage: 1.6.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
crypto: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ dart_internal: 0.2.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
file: 6.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
frontend_server_client: 3.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
glob: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -48,13 +49,13 @@
shelf_web_socket: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_map_stack_trace: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_maps: 0.10.12 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_core: 0.5.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- vm_service: 11.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_core: 0.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ vm_service: 11.7.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
-# PUBSPEC CHECKSUM: fe6e
+# PUBSPEC CHECKSUM: 7602
diff --git a/dev/tools/pubspec.yaml b/dev/tools/pubspec.yaml
index 92c0fc4..3003914 100644
--- a/dev/tools/pubspec.yaml
+++ b/dev/tools/pubspec.yaml
@@ -26,14 +26,15 @@
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
- test: 1.24.3
- test_api: 0.6.0
+ test: 1.24.4
+ test_api: 0.6.1
- _fe_analyzer_shared: 61.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- analyzer: 5.13.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ _fe_analyzer_shared: 62.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ analyzer: 6.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
convert: 3.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
coverage: 1.6.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ dart_internal: 0.2.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
frontend_server_client: 3.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
glob: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http_multi_server: 3.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -52,13 +53,13 @@
shelf_web_socket: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_map_stack_trace: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_maps: 0.10.12 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_core: 0.5.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- vm_service: 11.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_core: 0.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ vm_service: 11.7.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
-# PUBSPEC CHECKSUM: 7988
+# PUBSPEC CHECKSUM: 0d1c
diff --git a/dev/tools/vitool/pubspec.yaml b/dev/tools/vitool/pubspec.yaml
index 74fec64..26c8820 100644
--- a/dev/tools/vitool/pubspec.yaml
+++ b/dev/tools/vitool/pubspec.yaml
@@ -15,10 +15,10 @@
characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
collection: 1.17.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.9.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
petitparser: 5.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
flutter_test:
@@ -31,10 +31,10 @@
matcher: 0.12.16 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path: 1.8.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
-# PUBSPEC CHECKSUM: 79c6
+# PUBSPEC CHECKSUM: f7ed
diff --git a/dev/tracing_tests/pubspec.yaml b/dev/tracing_tests/pubspec.yaml
index b6b2a69..3ac5761 100644
--- a/dev/tracing_tests/pubspec.yaml
+++ b/dev/tracing_tests/pubspec.yaml
@@ -8,14 +8,14 @@
flutter:
sdk: flutter
- vm_service: 11.6.0
+ vm_service: 11.7.2
characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
collection: 1.17.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.9.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
flutter_test:
@@ -28,10 +28,10 @@
matcher: 0.12.16 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path: 1.8.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
-# PUBSPEC CHECKSUM: 39d4
+# PUBSPEC CHECKSUM: 07fe
diff --git a/examples/api/analysis_options.yaml b/examples/api/analysis_options.yaml
index 76be938..dec61f9 100644
--- a/examples/api/analysis_options.yaml
+++ b/examples/api/analysis_options.yaml
@@ -6,3 +6,5 @@
rules:
# Samples want to print things pretty often.
avoid_print: false
+ # Samples are sometimes incomplete and don't show usage of everything.
+ unreachable_from_main: false
diff --git a/examples/api/ios/Runner/Info.plist b/examples/api/ios/Runner/Info.plist
index 037c2ff..a48d067 100644
--- a/examples/api/ios/Runner/Info.plist
+++ b/examples/api/ios/Runner/Info.plist
@@ -39,8 +39,6 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
- <key>UIViewControllerBasedStatusBarAppearance</key>
- <false/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
diff --git a/examples/api/lib/material/action_buttons/action_icon_theme.0.dart b/examples/api/lib/material/action_buttons/action_icon_theme.0.dart
index 653b6ee..2067152 100644
--- a/examples/api/lib/material/action_buttons/action_icon_theme.0.dart
+++ b/examples/api/lib/material/action_buttons/action_icon_theme.0.dart
@@ -73,7 +73,13 @@
appBar: AppBar(
title: Text(title),
),
- drawer: const Drawer(),
+ drawer: Drawer(
+ child: Column(
+ children: <Widget>[
+ TextButton(child: const Text('Drawer Item'), onPressed: () {}),
+ ],
+ ),
+ ),
body: const Center(
child: NextPageButton(),
),
diff --git a/examples/api/lib/material/list_tile/list_tile.0.dart b/examples/api/lib/material/list_tile/list_tile.0.dart
index 50e7122..26226fb 100644
--- a/examples/api/lib/material/list_tile/list_tile.0.dart
+++ b/examples/api/lib/material/list_tile/list_tile.0.dart
@@ -20,19 +20,19 @@
),
useMaterial3: true,
),
- home: const LisTileExample(),
+ home: const ListTileExample(),
);
}
}
-class LisTileExample extends StatefulWidget {
- const LisTileExample({super.key});
+class ListTileExample extends StatefulWidget {
+ const ListTileExample({super.key});
@override
- State<LisTileExample> createState() => _LisTileExampleState();
+ State<ListTileExample> createState() => _ListTileExampleState();
}
-class _LisTileExampleState extends State<LisTileExample> with TickerProviderStateMixin {
+class _ListTileExampleState extends State<ListTileExample> with TickerProviderStateMixin {
late final AnimationController _fadeController;
late final AnimationController _sizeController;
late final Animation<double> _fadeAnimation;
diff --git a/examples/api/lib/material/list_tile/list_tile.1.dart b/examples/api/lib/material/list_tile/list_tile.1.dart
index 3ad480a..0f5f8bb 100644
--- a/examples/api/lib/material/list_tile/list_tile.1.dart
+++ b/examples/api/lib/material/list_tile/list_tile.1.dart
@@ -15,13 +15,13 @@
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(useMaterial3: true),
- home: const LisTileExample(),
+ home: const ListTileExample(),
);
}
}
-class LisTileExample extends StatelessWidget {
- const LisTileExample({super.key});
+class ListTileExample extends StatelessWidget {
+ const ListTileExample({super.key});
@override
Widget build(BuildContext context) {
diff --git a/examples/api/lib/material/list_tile/list_tile.selected.0.dart b/examples/api/lib/material/list_tile/list_tile.selected.0.dart
index 513bdde..c326774 100644
--- a/examples/api/lib/material/list_tile/list_tile.selected.0.dart
+++ b/examples/api/lib/material/list_tile/list_tile.selected.0.dart
@@ -15,19 +15,19 @@
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(useMaterial3: true),
- home: const LisTileExample(),
+ home: const ListTileExample(),
);
}
}
-class LisTileExample extends StatefulWidget {
- const LisTileExample({super.key});
+class ListTileExample extends StatefulWidget {
+ const ListTileExample({super.key});
@override
- State<LisTileExample> createState() => _LisTileExampleState();
+ State<ListTileExample> createState() => _ListTileExampleState();
}
-class _LisTileExampleState extends State<LisTileExample> {
+class _ListTileExampleState extends State<ListTileExample> {
int _selectedIndex = 0;
@override
diff --git a/examples/api/lib/material/navigation_bar/navigation_bar.0.dart b/examples/api/lib/material/navigation_bar/navigation_bar.0.dart
index b5ff01d..5c38b8c 100644
--- a/examples/api/lib/material/navigation_bar/navigation_bar.0.dart
+++ b/examples/api/lib/material/navigation_bar/navigation_bar.0.dart
@@ -13,7 +13,10 @@
@override
Widget build(BuildContext context) {
- return const MaterialApp(home: NavigationExample());
+ return MaterialApp(
+ theme: ThemeData(useMaterial3: true),
+ home: const NavigationExample(),
+ );
}
}
@@ -29,6 +32,7 @@
@override
Widget build(BuildContext context) {
+ final ThemeData theme = Theme.of(context);
return Scaffold(
bottomNavigationBar: NavigationBar(
onDestinationSelected: (int index) {
@@ -36,7 +40,7 @@
currentPageIndex = index;
});
},
- indicatorColor: Colors.amber[800],
+ indicatorColor: Colors.amber,
selectedIndex: currentPageIndex,
destinations: const <Widget>[
NavigationDestination(
@@ -45,31 +49,94 @@
label: 'Home',
),
NavigationDestination(
- icon: Icon(Icons.business),
- label: 'Business',
+ icon: Badge(child: Icon(Icons.notifications_sharp)),
+ label: 'Notifications',
),
NavigationDestination(
- selectedIcon: Icon(Icons.school),
- icon: Icon(Icons.school_outlined),
- label: 'School',
+ icon: Badge(
+ label: Text('2'),
+ child: Icon(Icons.messenger_sharp),
+ ),
+ label: 'Messages',
),
],
),
body: <Widget>[
- Container(
- color: Colors.red,
- alignment: Alignment.center,
- child: const Text('Page 1'),
+ /// Home page
+ Card(
+ shadowColor: Colors.transparent,
+ margin: const EdgeInsets.all(8.0),
+ child: SizedBox.expand(
+ child: Center(
+ child: Text(
+ 'Home page',
+ style: theme.textTheme.titleLarge,
+ ),
+ ),
+ ),
),
- Container(
- color: Colors.green,
- alignment: Alignment.center,
- child: const Text('Page 2'),
+ /// Notifications page
+ const Padding(
+ padding: EdgeInsets.all(8.0),
+ child: Column(
+ children: <Widget>[
+ Card(
+ child: ListTile(
+ leading: Icon(Icons.notifications_sharp),
+ title: Text('Notification 1'),
+ subtitle: Text('This is a notification'),
+ ),
+ ),
+ Card(
+ child: ListTile(
+ leading: Icon(Icons.notifications_sharp),
+ title: Text('Notification 2'),
+ subtitle: Text('This is a notification'),
+ ),
+ ),
+ ],
+ ),
),
- Container(
- color: Colors.blue,
- alignment: Alignment.center,
- child: const Text('Page 3'),
+ /// Messages page
+ ListView.builder(
+ reverse: true,
+ itemCount: 2,
+ itemBuilder: (BuildContext context, int index) {
+ if (index == 0) {
+ return Align(
+ alignment: Alignment.centerRight,
+ child: Container(
+ margin: const EdgeInsets.all(8.0),
+ padding: const EdgeInsets.all(8.0),
+ decoration: BoxDecoration(
+ color: theme.colorScheme.primary,
+ borderRadius: BorderRadius.circular(8.0),
+ ),
+ child: Text(
+ 'Hello',
+ style: theme.textTheme.bodyLarge!
+ .copyWith(color: theme.colorScheme.onPrimary),
+ ),
+ ),
+ );
+ }
+ return Align(
+ alignment: Alignment.centerLeft,
+ child: Container(
+ margin: const EdgeInsets.all(8.0),
+ padding: const EdgeInsets.all(8.0),
+ decoration: BoxDecoration(
+ color: theme.colorScheme.primary,
+ borderRadius: BorderRadius.circular(8.0),
+ ),
+ child: Text(
+ 'Hi!',
+ style: theme.textTheme.bodyLarge!
+ .copyWith(color: theme.colorScheme.onPrimary),
+ ),
+ ),
+ );
+ },
),
][currentPageIndex],
);
diff --git a/examples/api/lib/material/navigation_rail/navigation_rail.1.dart b/examples/api/lib/material/navigation_rail/navigation_rail.1.dart
index 812f334..f3e9437 100644
--- a/examples/api/lib/material/navigation_rail/navigation_rail.1.dart
+++ b/examples/api/lib/material/navigation_rail/navigation_rail.1.dart
@@ -14,7 +14,7 @@
@override
Widget build(BuildContext context) {
return MaterialApp(
- theme: ThemeData(colorSchemeSeed: const Color(0xff6750a4), useMaterial3: true),
+ theme: ThemeData(useMaterial3: true),
home: const NavRailExample(),
);
}
@@ -73,13 +73,19 @@
label: Text('First'),
),
NavigationRailDestination(
- icon: Icon(Icons.bookmark_border),
- selectedIcon: Icon(Icons.book),
+ icon: Badge(child: Icon(Icons.bookmark_border)),
+ selectedIcon: Badge(child: Icon(Icons.book)),
label: Text('Second'),
),
NavigationRailDestination(
- icon: Icon(Icons.star_border),
- selectedIcon: Icon(Icons.star),
+ icon: Badge(
+ label: Text('4'),
+ child: Icon(Icons.star_border),
+ ),
+ selectedIcon: Badge(
+ label: Text('4'),
+ child: Icon(Icons.star),
+ ),
label: Text('Third'),
),
],
diff --git a/examples/api/lib/material/refresh_indicator/refresh_indicator.1.dart b/examples/api/lib/material/refresh_indicator/refresh_indicator.1.dart
index aec4609..c389d40 100644
--- a/examples/api/lib/material/refresh_indicator/refresh_indicator.1.dart
+++ b/examples/api/lib/material/refresh_indicator/refresh_indicator.1.dart
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
/// Flutter code sample for [RefreshIndicator].
@@ -13,8 +14,9 @@
@override
Widget build(BuildContext context) {
- return const MaterialApp(
- home: RefreshIndicatorExample(),
+ return MaterialApp(
+ scrollBehavior: const MaterialScrollBehavior().copyWith(dragDevices: PointerDeviceKind.values.toSet()),
+ home: const RefreshIndicatorExample(),
);
}
}
@@ -40,17 +42,17 @@
// from the widget's children.
//
// By default this is set to `notification.depth == 0`, which ensures
- // the only the scroll notifications from the first child are listened to.
+ // the only the scroll notifications from the first scroll view are listened to.
//
// Here setting `notification.depth == 1` triggers the refresh indicator
// when overscrolling the nested scroll view.
notificationPredicate: (ScrollNotification notification) {
return notification.depth == 1;
},
- child: SingleChildScrollView(
- child: Column(
- children: <Widget>[
- Container(
+ child: CustomScrollView(
+ slivers: <Widget>[
+ SliverToBoxAdapter(
+ child: Container(
height: 100,
alignment: Alignment.center,
color: Colors.pink[100],
@@ -65,10 +67,12 @@
],
),
),
- Container(
+ ),
+ SliverToBoxAdapter(
+ child: Container(
color: Colors.green[100],
+ height: 300,
child: ListView.builder(
- shrinkWrap: true,
itemCount: 25,
itemBuilder: (BuildContext context, int index) {
return const ListTile(
@@ -78,8 +82,17 @@
},
),
),
- ],
- ),
+ ),
+ SliverList.builder(
+ itemCount: 20,
+ itemBuilder: (BuildContext context, int index) {
+ return const ListTile(
+ title: Text('Pull down here'),
+ subtitle: Text("Refresh indicator won't trigger"),
+ );
+ }
+ )
+ ],
),
),
);
diff --git a/examples/api/lib/material/search_anchor/search_anchor.3.dart b/examples/api/lib/material/search_anchor/search_anchor.3.dart
index 80694e0..e0eae6b 100644
--- a/examples/api/lib/material/search_anchor/search_anchor.3.dart
+++ b/examples/api/lib/material/search_anchor/search_anchor.3.dart
@@ -4,8 +4,7 @@
import 'package:flutter/material.dart';
-/// Flutter code sample for [SearchAnchor] that shows how to fetch the suggestions
-/// from a remote API.
+/// Flutter code sample for [SearchAnchor].
const Duration fakeAPIDuration = Duration(seconds: 1);
@@ -60,7 +59,7 @@
final List<String> options = (await _FakeAPI.search(_searchingWithQuery!)).toList();
// If another search happened after this one, throw away these options.
- // Use the previous options intead and wait for the newer request to
+ // Use the previous options instead and wait for the newer request to
// finish.
if (_searchingWithQuery != controller.text) {
return _lastOptions;
diff --git a/examples/api/lib/material/search_anchor/search_anchor.4.dart b/examples/api/lib/material/search_anchor/search_anchor.4.dart
index 8417ce6..d7e90ea 100644
--- a/examples/api/lib/material/search_anchor/search_anchor.4.dart
+++ b/examples/api/lib/material/search_anchor/search_anchor.4.dart
@@ -6,8 +6,7 @@
import 'package:flutter/material.dart';
-/// Flutter code sample for [SearchAnchor] that demonstrates fetching the
-/// suggestions asynchronously and debouncing the network calls.
+/// Flutter code sample for [SearchAnchor].
const Duration fakeAPIDuration = Duration(seconds: 1);
const Duration debounceDuration = Duration(milliseconds: 500);
diff --git a/examples/api/lib/material/selectable_region/selectable_region.0.dart b/examples/api/lib/material/selectable_region/selectable_region.0.dart
index 276cfd2..da20ccf 100644
--- a/examples/api/lib/material/selectable_region/selectable_region.0.dart
+++ b/examples/api/lib/material/selectable_region/selectable_region.0.dart
@@ -157,6 +157,7 @@
hasContent: true,
startSelectionPoint: isReversed ? secondSelectionPoint : firstSelectionPoint,
endSelectionPoint: isReversed ? firstSelectionPoint : secondSelectionPoint,
+ selectionRects: <Rect>[selectionRect],
);
}
}
diff --git a/examples/api/lib/material/snack_bar/snack_bar.2.dart b/examples/api/lib/material/snack_bar/snack_bar.2.dart
index 7a211be..63fca4d 100644
--- a/examples/api/lib/material/snack_bar/snack_bar.2.dart
+++ b/examples/api/lib/material/snack_bar/snack_bar.2.dart
@@ -4,12 +4,12 @@
import 'package:flutter/material.dart';
-/// Flutter code sample for [SnackBar] with Material 3 specifications.
+/// Flutter code sample for [SnackBar].
void main() => runApp(const SnackBarExampleApp());
-// A Material 3 [SnackBar] demonstrating an optional icon, in either floating
-// or fixed format.
+/// A Material 3 [SnackBar] demonstrating an optional icon, in either floating
+/// or fixed format.
class SnackBarExampleApp extends StatelessWidget {
const SnackBarExampleApp({super.key});
diff --git a/examples/api/lib/material/switch/switch.3.dart b/examples/api/lib/material/switch/switch.3.dart
index 023c338..b1ba74d 100644
--- a/examples/api/lib/material/switch/switch.3.dart
+++ b/examples/api/lib/material/switch/switch.3.dart
@@ -16,7 +16,7 @@
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.light(useMaterial3: true).copyWith(
- // Use the ambient [CupetinoThemeData] to style all widgets which would
+ // Use the ambient CupertinoThemeData to style all widgets which would
// otherwise use iOS defaults.
cupertinoOverrideTheme: const CupertinoThemeData(applyThemeToAll: true),
),
@@ -54,7 +54,7 @@
},
),
Switch.adaptive(
- // Don't use the ambient [CupetinoThemeData] to style this switch.
+ // Don't use the ambient CupertinoThemeData to style this switch.
applyCupertinoTheme: false,
value: light,
onChanged: (bool value) {
diff --git a/examples/api/lib/painting/linear_border/linear_border.0.dart b/examples/api/lib/painting/linear_border/linear_border.0.dart
index 991fa0f..510a652 100644
--- a/examples/api/lib/painting/linear_border/linear_border.0.dart
+++ b/examples/api/lib/painting/linear_border/linear_border.0.dart
@@ -2,10 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Examples of LinearBorder and LinearBorderEdge.
-
import 'package:flutter/material.dart';
+/// Examples for [LinearBorder] and [LinearBorderEdge].
+
void main() {
runApp(const ExampleApp());
}
@@ -18,7 +18,8 @@
return MaterialApp(
theme: ThemeData.light(useMaterial3: true),
home: const Directionality(
- textDirection: TextDirection.ltr, // Or try rtl.
+ // TRY THIS: Switch to TextDirection.rtl to see how the borders change.
+ textDirection: TextDirection.ltr,
child: Home(),
),
);
diff --git a/examples/api/lib/services/binding/handle_request_app_exit.0.dart b/examples/api/lib/services/binding/handle_request_app_exit.0.dart
index 3578f43..3757b31 100644
--- a/examples/api/lib/services/binding/handle_request_app_exit.0.dart
+++ b/examples/api/lib/services/binding/handle_request_app_exit.0.dart
@@ -79,30 +79,29 @@
return Center(
child: SizedBox(
width: 300,
- child: IntrinsicHeight(
- child: Column(
- children: <Widget>[
- RadioListTile<bool>(
- title: const Text('Do Not Allow Exit'),
- groupValue: _shouldExit,
- value: false,
- onChanged: _radioChanged,
- ),
- RadioListTile<bool>(
- title: const Text('Allow Exit'),
- groupValue: _shouldExit,
- value: true,
- onChanged: _radioChanged,
- ),
- const SizedBox(height: 30),
- ElevatedButton(
- onPressed: _quit,
- child: const Text('Quit'),
- ),
- const SizedBox(height: 30),
- Text(lastResponse),
- ],
- ),
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ children: <Widget>[
+ RadioListTile<bool>(
+ title: const Text('Do Not Allow Exit'),
+ groupValue: _shouldExit,
+ value: false,
+ onChanged: _radioChanged,
+ ),
+ RadioListTile<bool>(
+ title: const Text('Allow Exit'),
+ groupValue: _shouldExit,
+ value: true,
+ onChanged: _radioChanged,
+ ),
+ const SizedBox(height: 30),
+ ElevatedButton(
+ onPressed: _quit,
+ child: const Text('Quit'),
+ ),
+ const SizedBox(height: 30),
+ Text(lastResponse),
+ ],
),
),
);
diff --git a/examples/api/lib/widgets/heroes/hero.1.dart b/examples/api/lib/widgets/heroes/hero.1.dart
index f716862..63d6931 100644
--- a/examples/api/lib/widgets/heroes/hero.1.dart
+++ b/examples/api/lib/widgets/heroes/hero.1.dart
@@ -18,8 +18,9 @@
@override
Widget build(BuildContext context) {
- return const MaterialApp(
- home: HeroExample(),
+ return MaterialApp(
+ theme: ThemeData(useMaterial3: true),
+ home: const HeroExample(),
);
}
}
diff --git a/examples/api/lib/widgets/implicit_animations/animated_slide.0.dart b/examples/api/lib/widgets/implicit_animations/animated_slide.0.dart
index 8f6b94f..968955d 100644
--- a/examples/api/lib/widgets/implicit_animations/animated_slide.0.dart
+++ b/examples/api/lib/widgets/implicit_animations/animated_slide.0.dart
@@ -13,8 +13,9 @@
@override
Widget build(BuildContext context) {
- return const MaterialApp(
- home: AnimatedSlideExample(),
+ return MaterialApp(
+ theme: ThemeData(useMaterial3: true),
+ home: const AnimatedSlideExample(),
);
}
}
diff --git a/examples/api/lib/widgets/sliver/decorated_sliver.0.dart b/examples/api/lib/widgets/sliver/decorated_sliver.0.dart
new file mode 100644
index 0000000..5ccd9b9
--- /dev/null
+++ b/examples/api/lib/widgets/sliver/decorated_sliver.0.dart
@@ -0,0 +1,58 @@
+// Copyright 2014 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'package:flutter/material.dart';
+
+void main() => runApp(const SliverDecorationExampleApp());
+
+class SliverDecorationExampleApp extends StatelessWidget {
+ const SliverDecorationExampleApp({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return MaterialApp(
+ home: Scaffold(
+ appBar: AppBar(title: const Text('SliverDecoration Sample')),
+ body: const SliverDecorationExample(),
+ ),
+ );
+ }
+}
+
+class SliverDecorationExample extends StatelessWidget {
+ const SliverDecorationExample({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return CustomScrollView(
+ slivers: <Widget>[
+ DecoratedSliver(
+ decoration: const BoxDecoration(
+ gradient: RadialGradient(
+ center: Alignment(-0.5, -0.6),
+ radius: 0.15,
+ colors: <Color>[
+ Color(0xFFEEEEEE),
+ Color(0xFF111133),
+ ],
+ stops: <double>[0.9, 1.0],
+ ),
+ ),
+ sliver: SliverList(
+ delegate: SliverChildListDelegate(<Widget>[
+ const Text('Goodnight Moon'),
+ ]),
+ ),
+ ),
+ const DecoratedSliver(
+ decoration: BoxDecoration(
+ color: Colors.amber,
+ borderRadius: BorderRadius.all(Radius.circular(50))
+ ),
+ sliver: SliverToBoxAdapter(child: SizedBox(height: 300)),
+ ),
+ ],
+ );
+ }
+}
diff --git a/examples/api/lib/widgets/text_magnifier/text_magnifier.0.dart b/examples/api/lib/widgets/text_magnifier/text_magnifier.0.dart
index 3aa5f35..03daf7e 100644
--- a/examples/api/lib/widgets/text_magnifier/text_magnifier.0.dart
+++ b/examples/api/lib/widgets/text_magnifier/text_magnifier.0.dart
@@ -20,6 +20,7 @@
@override
Widget build(BuildContext context) {
return MaterialApp(
+ theme: ThemeData(useMaterial3: true),
home: Scaffold(
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 48.0),
diff --git a/examples/api/linux/flutter/generated_plugin_registrant.cc b/examples/api/linux/flutter/generated_plugin_registrant.cc
deleted file mode 100644
index e71a16d..0000000
--- a/examples/api/linux/flutter/generated_plugin_registrant.cc
+++ /dev/null
@@ -1,11 +0,0 @@
-//
-// Generated file. Do not edit.
-//
-
-// clang-format off
-
-#include "generated_plugin_registrant.h"
-
-
-void fl_register_plugins(FlPluginRegistry* registry) {
-}
diff --git a/examples/api/linux/flutter/generated_plugin_registrant.h b/examples/api/linux/flutter/generated_plugin_registrant.h
deleted file mode 100644
index e0f0a47..0000000
--- a/examples/api/linux/flutter/generated_plugin_registrant.h
+++ /dev/null
@@ -1,15 +0,0 @@
-//
-// Generated file. Do not edit.
-//
-
-// clang-format off
-
-#ifndef GENERATED_PLUGIN_REGISTRANT_
-#define GENERATED_PLUGIN_REGISTRANT_
-
-#include <flutter_linux/flutter_linux.h>
-
-// Registers Flutter plugins.
-void fl_register_plugins(FlPluginRegistry* registry);
-
-#endif // GENERATED_PLUGIN_REGISTRANT_
diff --git a/examples/api/linux/flutter/generated_plugins.cmake b/examples/api/linux/flutter/generated_plugins.cmake
deleted file mode 100644
index 2e1de87..0000000
--- a/examples/api/linux/flutter/generated_plugins.cmake
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Generated file, do not edit.
-#
-
-list(APPEND FLUTTER_PLUGIN_LIST
-)
-
-list(APPEND FLUTTER_FFI_PLUGIN_LIST
-)
-
-set(PLUGIN_BUNDLED_LIBRARIES)
-
-foreach(plugin ${FLUTTER_PLUGIN_LIST})
- add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin})
- target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
- list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
- list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
-endforeach(plugin)
-
-foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
- add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin})
- list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
-endforeach(ffi_plugin)
diff --git a/examples/api/pubspec.yaml b/examples/api/pubspec.yaml
index f7b8fab..73110a6 100644
--- a/examples/api/pubspec.yaml
+++ b/examples/api/pubspec.yaml
@@ -17,10 +17,10 @@
characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
collection: 1.17.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.9.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
integration_test:
@@ -31,10 +31,10 @@
sdk: flutter
flutter_test:
sdk: flutter
- test: 1.24.3
+ test: 1.24.4
- _fe_analyzer_shared: 61.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- analyzer: 5.13.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ _fe_analyzer_shared: 62.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ analyzer: 6.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
args: 2.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
async: 2.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -42,6 +42,7 @@
convert: 3.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
coverage: 1.6.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
crypto: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ dart_internal: 0.2.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
fake_async: 1.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
file: 6.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
frontend_server_client: 3.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -49,6 +50,7 @@
http_multi_server: 3.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http_parser: 4.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
io: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
logging: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
matcher: 0.12.16 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
mime: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -66,15 +68,15 @@
source_map_stack_trace: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_maps: 0.10.12 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
sync_http: 0.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_core: 0.5.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_core: 0.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- vm_service: 11.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ vm_service: 11.7.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -84,4 +86,4 @@
flutter:
uses-material-design: true
-# PUBSPEC CHECKSUM: d7e4
+# PUBSPEC CHECKSUM: 62ce
diff --git a/examples/api/test/material/navigation_bar/navigation_bar.0_test.dart b/examples/api/test/material/navigation_bar/navigation_bar.0_test.dart
index f18598a..d89d8db 100644
--- a/examples/api/test/material/navigation_bar/navigation_bar.0_test.dart
+++ b/examples/api/test/material/navigation_bar/navigation_bar.0_test.dart
@@ -17,20 +17,36 @@
/// NavigationDestinations must be rendered
expect(find.text('Home'), findsOneWidget);
- expect(find.text('Business'), findsOneWidget);
- expect(find.text('School'), findsOneWidget);
+ expect(find.text('Notifications'), findsOneWidget);
+ expect(find.text('Messages'), findsOneWidget);
- /// initial index must be zero
+ /// Test notification badge.
+ final Badge notificationBadge = tester.firstWidget(find.ancestor(
+ of: find.byIcon(Icons.notifications_sharp),
+ matching: find.byType(Badge),
+ ));
+ expect(notificationBadge.label, null);
+
+ /// Test messages badge.
+ final Badge messagesBadge = tester.firstWidget(find.ancestor(
+ of: find.byIcon(Icons.messenger_sharp),
+ matching: find.byType(Badge),
+ ));
+ expect(messagesBadge.label, isNotNull);
+
+ /// Initial index must be zero
expect(navigationBarWidget.selectedIndex, 0);
+ expect(find.text('Home page'), findsOneWidget);
- /// switch to second tab
- await tester.tap(find.text('Business'));
+ /// Switch to second tab
+ await tester.tap(find.text('Notifications'));
await tester.pumpAndSettle();
- expect(find.text('Page 2'), findsOneWidget);
+ expect(find.text('This is a notification'), findsNWidgets(2));
- /// switch to third tab
- await tester.tap(find.text('School'));
+ /// Switch to third tab
+ await tester.tap(find.text('Messages'));
await tester.pumpAndSettle();
- expect(find.text('Page 3'), findsOneWidget);
+ expect(find.text('Hi!'), findsOneWidget);
+ expect(find.text('Hello'), findsOneWidget);
});
}
diff --git a/examples/api/test/material/navigation_rail/navigation_rail.1_test.dart b/examples/api/test/material/navigation_rail/navigation_rail.1_test.dart
index 1c3eee1..d3526d4 100644
--- a/examples/api/test/material/navigation_rail/navigation_rail.1_test.dart
+++ b/examples/api/test/material/navigation_rail/navigation_rail.1_test.dart
@@ -94,4 +94,24 @@
expect(find.byType(FloatingActionButton), findsOneWidget);
expect(find.byType(IconButton), findsOneWidget);
});
+
+ testWidgets('Destinations have badge', (WidgetTester tester) async {
+ await tester.pumpWidget(
+ const example.NavigationRailExampleApp(),
+ );
+
+ // Test badge wthout label.
+ final Badge notificationBadge = tester.firstWidget(find.ancestor(
+ of: find.byIcon(Icons.bookmark_border),
+ matching: find.byType(Badge),
+ ));
+ expect(notificationBadge.label, null);
+
+ // Test badge with label.
+ final Badge messagesBadge = tester.firstWidget(find.ancestor(
+ of: find.byIcon(Icons.star_border),
+ matching: find.byType(Badge),
+ ));
+ expect(messagesBadge.label, isNotNull);
+ });
}
diff --git a/examples/api/test/painting/linear_gradient.0_test.dart b/examples/api/test/painting/linear_gradient.0_test.dart
index a3ced8c..12f0ed0 100644
--- a/examples/api/test/painting/linear_gradient.0_test.dart
+++ b/examples/api/test/painting/linear_gradient.0_test.dart
@@ -20,8 +20,9 @@
testWidgets('gradient matches golden', (WidgetTester tester) async {
await tester.pumpWidget(
- const MaterialApp(
- home: SizedBox(
+ MaterialApp(
+ theme: ThemeData(useMaterial3: true),
+ home: const SizedBox(
width: 800,
height: 600,
child: RepaintBoundary(
diff --git a/examples/api/test/widgets/heroes/hero.1_test.dart b/examples/api/test/widgets/heroes/hero.1_test.dart
index 18cd601..1fab344 100644
--- a/examples/api/test/widgets/heroes/hero.1_test.dart
+++ b/examples/api/test/widgets/heroes/hero.1_test.dart
@@ -22,7 +22,7 @@
// Jump 25% into the transition (total length = 300ms)
await tester.pump(const Duration(milliseconds: 75)); // 25% of 300ms
heroSize = tester.getSize(find.byType(Container).first);
- expect(heroSize.width.roundToDouble(), 171.0);
+ expect(heroSize.width.roundToDouble(), 170.0);
expect(heroSize.height.roundToDouble(), 73.0);
// Jump to 50% into the transition.
@@ -61,7 +61,7 @@
// Jump to 75% into the transition.
await tester.pump(const Duration(milliseconds: 75)); // 25% of 300ms
heroSize = tester.getSize(find.byType(Container).first);
- expect(heroSize.width.roundToDouble(), 171.0);
+ expect(heroSize.width.roundToDouble(), 170.0);
expect(heroSize.height.roundToDouble(), 73.0);
// Jump to 100% into the transition.
diff --git a/examples/api/test/widgets/implicit_animations/animated_slide.0_test.dart b/examples/api/test/widgets/implicit_animations/animated_slide.0_test.dart
index 13354bd..10746de 100644
--- a/examples/api/test/widgets/implicit_animations/animated_slide.0_test.dart
+++ b/examples/api/test/widgets/implicit_animations/animated_slide.0_test.dart
@@ -23,7 +23,7 @@
logoOffset = tester.getCenter(find.byType(FlutterLogo));
expect(logoOffset.dx.roundToDouble(), 376.0);
- expect(logoOffset.dy.roundToDouble(), 140.0);
+ expect(logoOffset.dy.roundToDouble(), 137.0);
// Test X axis slider.
final Offset x = tester.getCenter(find.text('X'));
@@ -32,6 +32,6 @@
logoOffset = tester.getCenter(find.byType(FlutterLogo));
expect(logoOffset.dx.roundToDouble(), 178.0);
- expect(logoOffset.dy.roundToDouble(), 140.0);
+ expect(logoOffset.dy.roundToDouble(), 137.0);
});
}
diff --git a/examples/api/windows/flutter/generated_plugin_registrant.cc b/examples/api/windows/flutter/generated_plugin_registrant.cc
deleted file mode 100644
index 8b6d468..0000000
--- a/examples/api/windows/flutter/generated_plugin_registrant.cc
+++ /dev/null
@@ -1,11 +0,0 @@
-//
-// Generated file. Do not edit.
-//
-
-// clang-format off
-
-#include "generated_plugin_registrant.h"
-
-
-void RegisterPlugins(flutter::PluginRegistry* registry) {
-}
diff --git a/examples/api/windows/flutter/generated_plugin_registrant.h b/examples/api/windows/flutter/generated_plugin_registrant.h
deleted file mode 100644
index dc139d8..0000000
--- a/examples/api/windows/flutter/generated_plugin_registrant.h
+++ /dev/null
@@ -1,15 +0,0 @@
-//
-// Generated file. Do not edit.
-//
-
-// clang-format off
-
-#ifndef GENERATED_PLUGIN_REGISTRANT_
-#define GENERATED_PLUGIN_REGISTRANT_
-
-#include <flutter/plugin_registry.h>
-
-// Registers Flutter plugins.
-void RegisterPlugins(flutter::PluginRegistry* registry);
-
-#endif // GENERATED_PLUGIN_REGISTRANT_
diff --git a/examples/api/windows/flutter/generated_plugins.cmake b/examples/api/windows/flutter/generated_plugins.cmake
deleted file mode 100644
index b93c4c3..0000000
--- a/examples/api/windows/flutter/generated_plugins.cmake
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Generated file, do not edit.
-#
-
-list(APPEND FLUTTER_PLUGIN_LIST
-)
-
-list(APPEND FLUTTER_FFI_PLUGIN_LIST
-)
-
-set(PLUGIN_BUNDLED_LIBRARIES)
-
-foreach(plugin ${FLUTTER_PLUGIN_LIST})
- add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin})
- target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
- list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
- list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
-endforeach(plugin)
-
-foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
- add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin})
- list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
-endforeach(ffi_plugin)
diff --git a/examples/flutter_view/ios/Runner/Info.plist b/examples/flutter_view/ios/Runner/Info.plist
index a74ef72..e826795 100644
--- a/examples/flutter_view/ios/Runner/Info.plist
+++ b/examples/flutter_view/ios/Runner/Info.plist
@@ -39,8 +39,6 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
- <key>UIViewControllerBasedStatusBarAppearance</key>
- <false/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
diff --git a/examples/flutter_view/pubspec.yaml b/examples/flutter_view/pubspec.yaml
index cba7496..e8d7749 100644
--- a/examples/flutter_view/pubspec.yaml
+++ b/examples/flutter_view/pubspec.yaml
@@ -10,14 +10,14 @@
characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
collection: 1.17.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.9.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
flutter:
uses-material-design: true
assets:
- assets/flutter-mark-square-64.png
-# PUBSPEC CHECKSUM: 3e9c
+# PUBSPEC CHECKSUM: a9c0
diff --git a/examples/flutter_view/windows/flutter/generated_plugins.cmake b/examples/flutter_view/windows/flutter/generated_plugins.cmake
deleted file mode 100644
index b93c4c3..0000000
--- a/examples/flutter_view/windows/flutter/generated_plugins.cmake
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Generated file, do not edit.
-#
-
-list(APPEND FLUTTER_PLUGIN_LIST
-)
-
-list(APPEND FLUTTER_FFI_PLUGIN_LIST
-)
-
-set(PLUGIN_BUNDLED_LIBRARIES)
-
-foreach(plugin ${FLUTTER_PLUGIN_LIST})
- add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin})
- target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
- list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
- list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
-endforeach(plugin)
-
-foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
- add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin})
- list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
-endforeach(ffi_plugin)
diff --git a/examples/hello_world/ios/Runner/GeneratedPluginRegistrant.h b/examples/hello_world/ios/Runner/GeneratedPluginRegistrant.h
deleted file mode 100644
index 7a89092..0000000
--- a/examples/hello_world/ios/Runner/GeneratedPluginRegistrant.h
+++ /dev/null
@@ -1,19 +0,0 @@
-//
-// Generated file. Do not edit.
-//
-
-// clang-format off
-
-#ifndef GeneratedPluginRegistrant_h
-#define GeneratedPluginRegistrant_h
-
-#import <Flutter/Flutter.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface GeneratedPluginRegistrant : NSObject
-+ (void)registerWithRegistry:(NSObject<FlutterPluginRegistry>*)registry;
-@end
-
-NS_ASSUME_NONNULL_END
-#endif /* GeneratedPluginRegistrant_h */
diff --git a/examples/hello_world/ios/Runner/GeneratedPluginRegistrant.m b/examples/hello_world/ios/Runner/GeneratedPluginRegistrant.m
deleted file mode 100644
index efe65ec..0000000
--- a/examples/hello_world/ios/Runner/GeneratedPluginRegistrant.m
+++ /dev/null
@@ -1,14 +0,0 @@
-//
-// Generated file. Do not edit.
-//
-
-// clang-format off
-
-#import "GeneratedPluginRegistrant.h"
-
-@implementation GeneratedPluginRegistrant
-
-+ (void)registerWithRegistry:(NSObject<FlutterPluginRegistry>*)registry {
-}
-
-@end
diff --git a/examples/hello_world/ios/Runner/Info.plist b/examples/hello_world/ios/Runner/Info.plist
index f5dc66f..b33e2ca 100644
--- a/examples/hello_world/ios/Runner/Info.plist
+++ b/examples/hello_world/ios/Runner/Info.plist
@@ -39,8 +39,6 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
- <key>UIViewControllerBasedStatusBarAppearance</key>
- <false/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
diff --git a/examples/hello_world/linux/flutter/generated_plugin_registrant.cc b/examples/hello_world/linux/flutter/generated_plugin_registrant.cc
deleted file mode 100644
index e71a16d..0000000
--- a/examples/hello_world/linux/flutter/generated_plugin_registrant.cc
+++ /dev/null
@@ -1,11 +0,0 @@
-//
-// Generated file. Do not edit.
-//
-
-// clang-format off
-
-#include "generated_plugin_registrant.h"
-
-
-void fl_register_plugins(FlPluginRegistry* registry) {
-}
diff --git a/examples/hello_world/linux/flutter/generated_plugin_registrant.h b/examples/hello_world/linux/flutter/generated_plugin_registrant.h
deleted file mode 100644
index e0f0a47..0000000
--- a/examples/hello_world/linux/flutter/generated_plugin_registrant.h
+++ /dev/null
@@ -1,15 +0,0 @@
-//
-// Generated file. Do not edit.
-//
-
-// clang-format off
-
-#ifndef GENERATED_PLUGIN_REGISTRANT_
-#define GENERATED_PLUGIN_REGISTRANT_
-
-#include <flutter_linux/flutter_linux.h>
-
-// Registers Flutter plugins.
-void fl_register_plugins(FlPluginRegistry* registry);
-
-#endif // GENERATED_PLUGIN_REGISTRANT_
diff --git a/examples/hello_world/linux/flutter/generated_plugins.cmake b/examples/hello_world/linux/flutter/generated_plugins.cmake
deleted file mode 100644
index 2e1de87..0000000
--- a/examples/hello_world/linux/flutter/generated_plugins.cmake
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Generated file, do not edit.
-#
-
-list(APPEND FLUTTER_PLUGIN_LIST
-)
-
-list(APPEND FLUTTER_FFI_PLUGIN_LIST
-)
-
-set(PLUGIN_BUNDLED_LIBRARIES)
-
-foreach(plugin ${FLUTTER_PLUGIN_LIST})
- add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin})
- target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
- list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
- list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
-endforeach(plugin)
-
-foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
- add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin})
- list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
-endforeach(ffi_plugin)
diff --git a/examples/hello_world/pubspec.yaml b/examples/hello_world/pubspec.yaml
index 0ca731d..b5ad48b 100644
--- a/examples/hello_world/pubspec.yaml
+++ b/examples/hello_world/pubspec.yaml
@@ -9,20 +9,20 @@
characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
collection: 1.17.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.9.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
flutter_driver:
sdk: flutter
flutter_test:
sdk: flutter
- test: 1.24.3
+ test: 1.24.4
- _fe_analyzer_shared: 61.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- analyzer: 5.13.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ _fe_analyzer_shared: 62.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ analyzer: 6.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
args: 2.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
async: 2.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -30,6 +30,7 @@
convert: 3.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
coverage: 1.6.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
crypto: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ dart_internal: 0.2.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
fake_async: 1.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
file: 6.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
frontend_server_client: 3.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -37,6 +38,7 @@
http_multi_server: 3.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http_parser: 4.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
io: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
logging: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
matcher: 0.12.16 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
mime: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -52,19 +54,19 @@
source_map_stack_trace: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_maps: 0.10.12 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
sync_http: 0.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_core: 0.5.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_core: 0.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- vm_service: 11.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ vm_service: 11.7.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
-# PUBSPEC CHECKSUM: db36
+# PUBSPEC CHECKSUM: be20
diff --git a/examples/hello_world/windows/flutter/generated_plugin_registrant.cc b/examples/hello_world/windows/flutter/generated_plugin_registrant.cc
deleted file mode 100644
index 8b6d468..0000000
--- a/examples/hello_world/windows/flutter/generated_plugin_registrant.cc
+++ /dev/null
@@ -1,11 +0,0 @@
-//
-// Generated file. Do not edit.
-//
-
-// clang-format off
-
-#include "generated_plugin_registrant.h"
-
-
-void RegisterPlugins(flutter::PluginRegistry* registry) {
-}
diff --git a/examples/hello_world/windows/flutter/generated_plugin_registrant.h b/examples/hello_world/windows/flutter/generated_plugin_registrant.h
deleted file mode 100644
index dc139d8..0000000
--- a/examples/hello_world/windows/flutter/generated_plugin_registrant.h
+++ /dev/null
@@ -1,15 +0,0 @@
-//
-// Generated file. Do not edit.
-//
-
-// clang-format off
-
-#ifndef GENERATED_PLUGIN_REGISTRANT_
-#define GENERATED_PLUGIN_REGISTRANT_
-
-#include <flutter/plugin_registry.h>
-
-// Registers Flutter plugins.
-void RegisterPlugins(flutter::PluginRegistry* registry);
-
-#endif // GENERATED_PLUGIN_REGISTRANT_
diff --git a/examples/hello_world/windows/flutter/generated_plugins.cmake b/examples/hello_world/windows/flutter/generated_plugins.cmake
deleted file mode 100644
index b93c4c3..0000000
--- a/examples/hello_world/windows/flutter/generated_plugins.cmake
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Generated file, do not edit.
-#
-
-list(APPEND FLUTTER_PLUGIN_LIST
-)
-
-list(APPEND FLUTTER_FFI_PLUGIN_LIST
-)
-
-set(PLUGIN_BUNDLED_LIBRARIES)
-
-foreach(plugin ${FLUTTER_PLUGIN_LIST})
- add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin})
- target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
- list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
- list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
-endforeach(plugin)
-
-foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
- add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin})
- list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
-endforeach(ffi_plugin)
diff --git a/examples/image_list/ios/Runner/Info.plist b/examples/image_list/ios/Runner/Info.plist
index c9198ba..2f1b82c 100644
--- a/examples/image_list/ios/Runner/Info.plist
+++ b/examples/image_list/ios/Runner/Info.plist
@@ -39,8 +39,6 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
- <key>UIViewControllerBasedStatusBarAppearance</key>
- <false/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
diff --git a/examples/image_list/pubspec.yaml b/examples/image_list/pubspec.yaml
index 5dfec59..b082083 100644
--- a/examples/image_list/pubspec.yaml
+++ b/examples/image_list/pubspec.yaml
@@ -16,10 +16,10 @@
characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
collection: 1.17.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.9.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
flutter_test:
@@ -37,11 +37,11 @@
matcher: 0.12.16 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path: 1.8.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
flutter:
@@ -54,4 +54,4 @@
assets:
- images/coast.jpg
-# PUBSPEC CHECKSUM: 3dc5
+# PUBSPEC CHECKSUM: beec
diff --git a/examples/layers/ios/Runner/Info.plist b/examples/layers/ios/Runner/Info.plist
index 2990f68..04927c5 100644
--- a/examples/layers/ios/Runner/Info.plist
+++ b/examples/layers/ios/Runner/Info.plist
@@ -39,8 +39,6 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
- <key>UIViewControllerBasedStatusBarAppearance</key>
- <false/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
diff --git a/examples/layers/pubspec.yaml b/examples/layers/pubspec.yaml
index 603f7d3..4a83ace 100644
--- a/examples/layers/pubspec.yaml
+++ b/examples/layers/pubspec.yaml
@@ -9,10 +9,10 @@
characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
collection: 1.17.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.9.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
flutter_test:
@@ -25,15 +25,15 @@
matcher: 0.12.16 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path: 1.8.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
flutter:
assets:
- services/data.json
uses-material-design: true
-# PUBSPEC CHECKSUM: d91e
+# PUBSPEC CHECKSUM: 7f45
diff --git a/examples/layers/raw/canvas.dart b/examples/layers/raw/canvas.dart
index 2d178cf..8af0ca2 100644
--- a/examples/layers/raw/canvas.dart
+++ b/examples/layers/raw/canvas.dart
@@ -96,7 +96,7 @@
// the rectangle and smaller circle.
canvas.drawCircle(const ui.Offset(150.0, 300.0), radius, paint);
- // When we're done issuing painting commands, we end the recording an receive
+ // When we're done issuing painting commands, we end the recording and receive
// a Picture, which is an immutable record of the commands we've issued. You
// can draw a Picture into another canvas or include it as part of a
// composited scene.
diff --git a/examples/platform_channel/ios/Runner/Info.plist b/examples/platform_channel/ios/Runner/Info.plist
index ecc52c8..97a48d5 100644
--- a/examples/platform_channel/ios/Runner/Info.plist
+++ b/examples/platform_channel/ios/Runner/Info.plist
@@ -39,8 +39,6 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
- <key>UIViewControllerBasedStatusBarAppearance</key>
- <false/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
diff --git a/examples/platform_channel/linux/flutter/generated_plugin_registrant.cc b/examples/platform_channel/linux/flutter/generated_plugin_registrant.cc
deleted file mode 100644
index e71a16d..0000000
--- a/examples/platform_channel/linux/flutter/generated_plugin_registrant.cc
+++ /dev/null
@@ -1,11 +0,0 @@
-//
-// Generated file. Do not edit.
-//
-
-// clang-format off
-
-#include "generated_plugin_registrant.h"
-
-
-void fl_register_plugins(FlPluginRegistry* registry) {
-}
diff --git a/examples/platform_channel/linux/flutter/generated_plugin_registrant.h b/examples/platform_channel/linux/flutter/generated_plugin_registrant.h
deleted file mode 100644
index e0f0a47..0000000
--- a/examples/platform_channel/linux/flutter/generated_plugin_registrant.h
+++ /dev/null
@@ -1,15 +0,0 @@
-//
-// Generated file. Do not edit.
-//
-
-// clang-format off
-
-#ifndef GENERATED_PLUGIN_REGISTRANT_
-#define GENERATED_PLUGIN_REGISTRANT_
-
-#include <flutter_linux/flutter_linux.h>
-
-// Registers Flutter plugins.
-void fl_register_plugins(FlPluginRegistry* registry);
-
-#endif // GENERATED_PLUGIN_REGISTRANT_
diff --git a/examples/platform_channel/linux/flutter/generated_plugins.cmake b/examples/platform_channel/linux/flutter/generated_plugins.cmake
deleted file mode 100644
index 2e1de87..0000000
--- a/examples/platform_channel/linux/flutter/generated_plugins.cmake
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Generated file, do not edit.
-#
-
-list(APPEND FLUTTER_PLUGIN_LIST
-)
-
-list(APPEND FLUTTER_FFI_PLUGIN_LIST
-)
-
-set(PLUGIN_BUNDLED_LIBRARIES)
-
-foreach(plugin ${FLUTTER_PLUGIN_LIST})
- add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin})
- target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
- list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
- list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
-endforeach(plugin)
-
-foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
- add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin})
- list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
-endforeach(ffi_plugin)
diff --git a/examples/platform_channel/pubspec.yaml b/examples/platform_channel/pubspec.yaml
index 76fc118..a6026f5 100644
--- a/examples/platform_channel/pubspec.yaml
+++ b/examples/platform_channel/pubspec.yaml
@@ -9,20 +9,20 @@
characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
collection: 1.17.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.9.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
flutter_test:
sdk: flutter
flutter_driver:
sdk: flutter
- test: 1.24.3
+ test: 1.24.4
- _fe_analyzer_shared: 61.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- analyzer: 5.13.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ _fe_analyzer_shared: 62.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ analyzer: 6.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
args: 2.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
async: 2.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -30,6 +30,7 @@
convert: 3.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
coverage: 1.6.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
crypto: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ dart_internal: 0.2.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
fake_async: 1.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
file: 6.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
frontend_server_client: 3.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -37,6 +38,7 @@
http_multi_server: 3.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http_parser: 4.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
io: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
logging: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
matcher: 0.12.16 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
mime: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -52,15 +54,15 @@
source_map_stack_trace: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_maps: 0.10.12 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
sync_http: 0.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_core: 0.5.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_core: 0.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- vm_service: 11.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ vm_service: 11.7.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -70,4 +72,4 @@
flutter:
uses-material-design: true
-# PUBSPEC CHECKSUM: db36
+# PUBSPEC CHECKSUM: be20
diff --git a/examples/platform_channel/windows/flutter/generated_plugin_registrant.cc b/examples/platform_channel/windows/flutter/generated_plugin_registrant.cc
deleted file mode 100644
index 8b6d468..0000000
--- a/examples/platform_channel/windows/flutter/generated_plugin_registrant.cc
+++ /dev/null
@@ -1,11 +0,0 @@
-//
-// Generated file. Do not edit.
-//
-
-// clang-format off
-
-#include "generated_plugin_registrant.h"
-
-
-void RegisterPlugins(flutter::PluginRegistry* registry) {
-}
diff --git a/examples/platform_channel/windows/flutter/generated_plugin_registrant.h b/examples/platform_channel/windows/flutter/generated_plugin_registrant.h
deleted file mode 100644
index dc139d8..0000000
--- a/examples/platform_channel/windows/flutter/generated_plugin_registrant.h
+++ /dev/null
@@ -1,15 +0,0 @@
-//
-// Generated file. Do not edit.
-//
-
-// clang-format off
-
-#ifndef GENERATED_PLUGIN_REGISTRANT_
-#define GENERATED_PLUGIN_REGISTRANT_
-
-#include <flutter/plugin_registry.h>
-
-// Registers Flutter plugins.
-void RegisterPlugins(flutter::PluginRegistry* registry);
-
-#endif // GENERATED_PLUGIN_REGISTRANT_
diff --git a/examples/platform_channel/windows/flutter/generated_plugins.cmake b/examples/platform_channel/windows/flutter/generated_plugins.cmake
deleted file mode 100644
index b93c4c3..0000000
--- a/examples/platform_channel/windows/flutter/generated_plugins.cmake
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Generated file, do not edit.
-#
-
-list(APPEND FLUTTER_PLUGIN_LIST
-)
-
-list(APPEND FLUTTER_FFI_PLUGIN_LIST
-)
-
-set(PLUGIN_BUNDLED_LIBRARIES)
-
-foreach(plugin ${FLUTTER_PLUGIN_LIST})
- add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin})
- target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
- list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
- list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
-endforeach(plugin)
-
-foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
- add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin})
- list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
-endforeach(ffi_plugin)
diff --git a/examples/platform_channel_swift/ios/Runner/Info.plist b/examples/platform_channel_swift/ios/Runner/Info.plist
index ecc52c8..97a48d5 100644
--- a/examples/platform_channel_swift/ios/Runner/Info.plist
+++ b/examples/platform_channel_swift/ios/Runner/Info.plist
@@ -39,8 +39,6 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
- <key>UIViewControllerBasedStatusBarAppearance</key>
- <false/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
diff --git a/examples/platform_channel_swift/pubspec.yaml b/examples/platform_channel_swift/pubspec.yaml
index aadd1d2..7b2164b 100644
--- a/examples/platform_channel_swift/pubspec.yaml
+++ b/examples/platform_channel_swift/pubspec.yaml
@@ -9,20 +9,20 @@
characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
collection: 1.17.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.9.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
flutter_test:
sdk: flutter
flutter_driver:
sdk: flutter
- test: 1.24.3
+ test: 1.24.4
- _fe_analyzer_shared: 61.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- analyzer: 5.13.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ _fe_analyzer_shared: 62.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ analyzer: 6.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
args: 2.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
async: 2.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -30,6 +30,7 @@
convert: 3.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
coverage: 1.6.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
crypto: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ dart_internal: 0.2.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
fake_async: 1.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
file: 6.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
frontend_server_client: 3.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -37,6 +38,7 @@
http_multi_server: 3.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http_parser: 4.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
io: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
logging: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
matcher: 0.12.16 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
mime: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -52,15 +54,15 @@
source_map_stack_trace: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_maps: 0.10.12 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
sync_http: 0.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_core: 0.5.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_core: 0.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- vm_service: 11.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ vm_service: 11.7.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -70,4 +72,4 @@
flutter:
uses-material-design: true
-# PUBSPEC CHECKSUM: db36
+# PUBSPEC CHECKSUM: be20
diff --git a/examples/platform_view/ios/Runner/Info.plist b/examples/platform_view/ios/Runner/Info.plist
index b678842..ca51ebe 100644
--- a/examples/platform_view/ios/Runner/Info.plist
+++ b/examples/platform_view/ios/Runner/Info.plist
@@ -39,8 +39,6 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
- <key>UIViewControllerBasedStatusBarAppearance</key>
- <false/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
diff --git a/examples/platform_view/lib/main.dart b/examples/platform_view/lib/main.dart
index 198dcdf..6e0e890 100644
--- a/examples/platform_view/lib/main.dart
+++ b/examples/platform_view/lib/main.dart
@@ -57,8 +57,9 @@
return const Text('Continue in Windows view');
case TargetPlatform.macOS:
return const Text('Continue in macOS view');
- case TargetPlatform.fuchsia:
case TargetPlatform.linux:
+ return const Text('Continue in Linux view');
+ case TargetPlatform.fuchsia:
throw UnimplementedError('Platform not yet implemented');
}
}
diff --git a/examples/platform_view/linux/CMakeLists.txt b/examples/platform_view/linux/CMakeLists.txt
new file mode 100644
index 0000000..67f2897
--- /dev/null
+++ b/examples/platform_view/linux/CMakeLists.txt
@@ -0,0 +1,140 @@
+# Project-level configuration.
+cmake_minimum_required(VERSION 3.10)
+project(runner LANGUAGES CXX)
+set(CMAKE_CXX_STANDARD 17)
+
+# The name of the executable created for the application. Change this to change
+# the on-disk name of your application.
+set(BINARY_NAME "platform_view")
+# The unique GTK application identifier for this application. See:
+# https://wiki.gnome.org/HowDoI/ChooseApplicationID
+set(APPLICATION_ID "io.flutter.examples.platform_view")
+
+# Explicitly opt in to modern CMake behaviors to avoid warnings with recent
+# versions of CMake.
+cmake_policy(SET CMP0063 NEW)
+
+# Load bundled libraries from the lib/ directory relative to the binary.
+set(CMAKE_INSTALL_RPATH "$ORIGIN/lib")
+
+# Root filesystem for cross-building.
+if(FLUTTER_TARGET_PLATFORM_SYSROOT)
+ set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT})
+ set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})
+ set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
+ set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+ set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+endif()
+
+# Define build configuration options.
+if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
+ set(CMAKE_BUILD_TYPE "Debug" CACHE
+ STRING "Flutter build mode" FORCE)
+ set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
+ "Debug" "Profile" "Release")
+endif()
+
+# Compilation settings that should be applied to most targets.
+#
+# Be cautious about adding new options here, as plugins use this function by
+# default. In most cases, you should add new options to specific targets instead
+# of modifying this function.
+function(APPLY_STANDARD_SETTINGS TARGET)
+ target_compile_features(${TARGET} PUBLIC cxx_std_14)
+ target_compile_options(${TARGET} PRIVATE -Wall -Werror)
+ target_compile_options(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:-O3>")
+ target_compile_definitions(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:NDEBUG>")
+endfunction()
+
+# Flutter library and tool build rules.
+set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter")
+add_subdirectory(${FLUTTER_MANAGED_DIR})
+
+# System-level dependencies.
+find_package(PkgConfig REQUIRED)
+pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
+
+add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}")
+
+# Define the application target. To change its name, change BINARY_NAME above,
+# not the value here, or `flutter run` will no longer work.
+#
+# Any new source files that you add to the application should be added here.
+add_executable(${BINARY_NAME}
+ "main.cc"
+ "my_application.cc"
+ "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
+)
+
+# Apply the standard set of build settings. This can be removed for applications
+# that need different build settings.
+apply_standard_settings(${BINARY_NAME})
+
+# Add dependency libraries. Add any application-specific dependencies here.
+target_link_libraries(${BINARY_NAME} PRIVATE flutter)
+target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK)
+
+# Run the Flutter tool portions of the build. This must not be removed.
+add_dependencies(${BINARY_NAME} flutter_assemble)
+
+# Only the install-generated bundle's copy of the executable will launch
+# correctly, since the resources must in the right relative locations. To avoid
+# people trying to run the unbundled copy, put it in a subdirectory instead of
+# the default top-level location.
+set_target_properties(${BINARY_NAME}
+ PROPERTIES
+ RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run"
+)
+
+
+# Generated plugin build rules, which manage building the plugins and adding
+# them to the application.
+include(flutter/generated_plugins.cmake)
+
+
+# === Installation ===
+# By default, "installing" just makes a relocatable bundle in the build
+# directory.
+set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle")
+if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
+ set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE)
+endif()
+
+# Start with a clean build bundle directory every time.
+install(CODE "
+ file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\")
+ " COMPONENT Runtime)
+
+set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data")
+set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib")
+
+install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}"
+ COMPONENT Runtime)
+
+install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
+ COMPONENT Runtime)
+
+install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
+ COMPONENT Runtime)
+
+foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES})
+ install(FILES "${bundled_library}"
+ DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
+ COMPONENT Runtime)
+endforeach(bundled_library)
+
+# Fully re-copy the assets directory on each build to avoid having stale files
+# from a previous install.
+set(FLUTTER_ASSET_DIR_NAME "flutter_assets")
+install(CODE "
+ file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\")
+ " COMPONENT Runtime)
+install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}"
+ DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime)
+
+# Install the AOT library on non-Debug builds only.
+if(NOT CMAKE_BUILD_TYPE MATCHES "Debug")
+ install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
+ COMPONENT Runtime)
+endif()
diff --git a/examples/platform_view/linux/flutter/CMakeLists.txt b/examples/platform_view/linux/flutter/CMakeLists.txt
new file mode 100644
index 0000000..d5bd016
--- /dev/null
+++ b/examples/platform_view/linux/flutter/CMakeLists.txt
@@ -0,0 +1,88 @@
+# This file controls Flutter-level build steps. It should not be edited.
+cmake_minimum_required(VERSION 3.10)
+
+set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral")
+
+# Configuration provided via flutter tool.
+include(${EPHEMERAL_DIR}/generated_config.cmake)
+
+# TODO: Move the rest of this into files in ephemeral. See
+# https://github.com/flutter/flutter/issues/57146.
+
+# Serves the same purpose as list(TRANSFORM ... PREPEND ...),
+# which isn't available in 3.10.
+function(list_prepend LIST_NAME PREFIX)
+ set(NEW_LIST "")
+ foreach(element ${${LIST_NAME}})
+ list(APPEND NEW_LIST "${PREFIX}${element}")
+ endforeach(element)
+ set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE)
+endfunction()
+
+# === Flutter Library ===
+# System-level dependencies.
+find_package(PkgConfig REQUIRED)
+pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
+pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0)
+pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0)
+
+set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so")
+
+# Published to parent scope for install step.
+set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE)
+set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE)
+set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE)
+set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE)
+
+list(APPEND FLUTTER_LIBRARY_HEADERS
+ "fl_basic_message_channel.h"
+ "fl_binary_codec.h"
+ "fl_binary_messenger.h"
+ "fl_dart_project.h"
+ "fl_engine.h"
+ "fl_json_message_codec.h"
+ "fl_json_method_codec.h"
+ "fl_message_codec.h"
+ "fl_method_call.h"
+ "fl_method_channel.h"
+ "fl_method_codec.h"
+ "fl_method_response.h"
+ "fl_plugin_registrar.h"
+ "fl_plugin_registry.h"
+ "fl_standard_message_codec.h"
+ "fl_standard_method_codec.h"
+ "fl_string_codec.h"
+ "fl_value.h"
+ "fl_view.h"
+ "flutter_linux.h"
+)
+list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/")
+add_library(flutter INTERFACE)
+target_include_directories(flutter INTERFACE
+ "${EPHEMERAL_DIR}"
+)
+target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}")
+target_link_libraries(flutter INTERFACE
+ PkgConfig::GTK
+ PkgConfig::GLIB
+ PkgConfig::GIO
+)
+add_dependencies(flutter flutter_assemble)
+
+# === Flutter tool backend ===
+# _phony_ is a non-existent file to force this command to run every time,
+# since currently there's no way to get a full input/output list from the
+# flutter tool.
+add_custom_command(
+ OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS}
+ ${CMAKE_CURRENT_BINARY_DIR}/_phony_
+ COMMAND ${CMAKE_COMMAND} -E env
+ ${FLUTTER_TOOL_ENVIRONMENT}
+ "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh"
+ ${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE}
+ VERBATIM
+)
+add_custom_target(flutter_assemble DEPENDS
+ "${FLUTTER_LIBRARY}"
+ ${FLUTTER_LIBRARY_HEADERS}
+)
diff --git a/examples/platform_view/linux/main.cc b/examples/platform_view/linux/main.cc
new file mode 100644
index 0000000..281a29e
--- /dev/null
+++ b/examples/platform_view/linux/main.cc
@@ -0,0 +1,10 @@
+// Copyright 2014 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "my_application.h"
+
+int main(int argc, char** argv) {
+ g_autoptr(MyApplication) app = my_application_new();
+ return g_application_run(G_APPLICATION(app), argc, argv);
+}
diff --git a/examples/platform_view/linux/my_application.cc b/examples/platform_view/linux/my_application.cc
new file mode 100644
index 0000000..403df87
--- /dev/null
+++ b/examples/platform_view/linux/my_application.cc
@@ -0,0 +1,167 @@
+// Copyright 2014 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "my_application.h"
+
+#include <flutter_linux/flutter_linux.h>
+
+#ifdef GDK_WINDOWING_X11
+#include <gdk/gdkx.h>
+#endif
+
+#include "flutter/generated_plugin_registrant.h"
+
+struct _MyApplication {
+ GtkApplication parent_instance;
+
+ // Channel to receive platform view requests from Flutter.
+ FlMethodChannel* platform_view_channel;
+
+ // Main window.
+ GtkWindow* window;
+
+ // Current counter.
+ int64_t counter;
+
+ // Request in progress.
+ FlMethodCall* method_call;
+
+ // Native window requested by Flutter.
+ GtkWindow* native_window;
+
+ // Label to show count.
+ GtkLabel* counter_label;
+};
+
+G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION)
+
+static void update_counter_label(MyApplication* self) {
+ g_autofree gchar* text =
+ g_strdup_printf("Button tapped %" G_GINT64_FORMAT " %s.", self->counter,
+ self->counter == 1 ? "time" : "times");
+ gtk_label_set_text(self->counter_label, text);
+}
+
+static void button_clicked_cb(MyApplication* self) {
+ self->counter++;
+ update_counter_label(self);
+}
+
+static void native_window_delete_event_cb(MyApplication* self,
+ gint response_id) {
+ g_autoptr(FlValue) counter_value = fl_value_new_int(self->counter);
+ fl_method_call_respond_success(self->method_call, counter_value, nullptr);
+ g_clear_object(&self->method_call);
+}
+
+// Handle request to switch the view.
+static void handle_switch_view(MyApplication* self, FlMethodCall* method_call) {
+ FlValue* counter_value = fl_method_call_get_args(method_call);
+ if (fl_value_get_type(counter_value) != FL_VALUE_TYPE_INT) {
+ fl_method_call_respond_error(self->method_call, "Invalid args",
+ "Invalid switchView args", nullptr, nullptr);
+ return;
+ }
+
+ self->counter = fl_value_get_int(counter_value);
+ self->method_call = FL_METHOD_CALL(g_object_ref(method_call));
+
+ // Show the same UI in a native window.
+ self->native_window = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
+ gtk_window_set_transient_for(self->native_window, self->window);
+ gtk_window_set_modal(self->native_window, TRUE);
+ gtk_window_set_destroy_with_parent(self->native_window, TRUE);
+ g_signal_connect_swapped(self->native_window, "delete-event",
+ G_CALLBACK(native_window_delete_event_cb), self);
+
+ GtkWidget* box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 12);
+ gtk_widget_set_margin_start(box, 24);
+ gtk_widget_set_margin_end(box, 24);
+ gtk_widget_set_margin_top(box, 24);
+ gtk_widget_set_margin_bottom(box, 24);
+ gtk_widget_show(box);
+ gtk_container_add(GTK_CONTAINER(self->native_window), box);
+
+ self->counter_label = GTK_LABEL(gtk_label_new(""));
+ gtk_widget_show(GTK_WIDGET(self->counter_label));
+ gtk_container_add(GTK_CONTAINER(box), GTK_WIDGET(self->counter_label));
+
+ GtkWidget* button = gtk_button_new_with_label("+");
+ gtk_style_context_add_class(gtk_widget_get_style_context(GTK_WIDGET(button)),
+ "circular");
+ gtk_widget_set_halign(button, GTK_ALIGN_CENTER);
+ gtk_widget_show(button);
+ gtk_container_add(GTK_CONTAINER(box), button);
+ g_signal_connect_swapped(button, "clicked", G_CALLBACK(button_clicked_cb),
+ self);
+
+ update_counter_label(self);
+
+ gtk_window_present(self->native_window);
+}
+
+// Handle platform view requests from Flutter.
+static void platform_view_channel_method_cb(FlMethodChannel* channel,
+ FlMethodCall* method_call,
+ gpointer user_data) {
+ MyApplication* self = MY_APPLICATION(user_data);
+
+ const char* name = fl_method_call_get_name(method_call);
+ if (g_str_equal(name, "switchView")) {
+ handle_switch_view(self, method_call);
+ } else {
+ fl_method_call_respond_not_implemented(method_call, nullptr);
+ }
+}
+
+// Implements GObject::dispose.
+static void my_application_dispose(GObject* object) {
+ MyApplication* self = MY_APPLICATION(object);
+
+ g_clear_object(&self->platform_view_channel);
+
+ G_OBJECT_CLASS(my_application_parent_class)->dispose(object);
+}
+
+// Implements GApplication::activate.
+static void my_application_activate(GApplication* application) {
+ MyApplication* self = MY_APPLICATION(application);
+ self->window =
+ GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application)));
+
+ gtk_window_set_default_size(self->window, 1280, 720);
+ gtk_widget_show(GTK_WIDGET(self->window));
+
+ g_autoptr(FlDartProject) project = fl_dart_project_new();
+ FlView* view = fl_view_new(project);
+ gtk_widget_show(GTK_WIDGET(view));
+ gtk_container_add(GTK_CONTAINER(self->window), GTK_WIDGET(view));
+
+ // Create channel to handle platform view requests from Flutter.
+ FlEngine* engine = fl_view_get_engine(view);
+ g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new();
+ self->platform_view_channel = fl_method_channel_new(
+ fl_engine_get_binary_messenger(engine),
+ "samples.flutter.io/platform_view", FL_METHOD_CODEC(codec));
+ fl_method_channel_set_method_call_handler(self->platform_view_channel,
+ platform_view_channel_method_cb,
+ self, nullptr);
+
+ fl_register_plugins(FL_PLUGIN_REGISTRY(view));
+
+ gtk_widget_grab_focus(GTK_WIDGET(view));
+}
+
+static void my_application_class_init(MyApplicationClass* klass) {
+ G_OBJECT_CLASS(klass)->dispose = my_application_dispose;
+ G_APPLICATION_CLASS(klass)->activate = my_application_activate;
+}
+
+static void my_application_init(MyApplication* self) {}
+
+MyApplication* my_application_new() {
+ return MY_APPLICATION(g_object_new(my_application_get_type(),
+ "application-id", APPLICATION_ID, "flags",
+ G_APPLICATION_NON_UNIQUE, nullptr));
+}
diff --git a/examples/platform_view/linux/my_application.h b/examples/platform_view/linux/my_application.h
new file mode 100644
index 0000000..8c66ec4
--- /dev/null
+++ b/examples/platform_view/linux/my_application.h
@@ -0,0 +1,22 @@
+// Copyright 2014 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef FLUTTER_MY_APPLICATION_H_
+#define FLUTTER_MY_APPLICATION_H_
+
+#include <gtk/gtk.h>
+
+G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION,
+ GtkApplication)
+
+/**
+ * my_application_new:
+ *
+ * Creates a new Flutter-based application.
+ *
+ * Returns: a new #MyApplication.
+ */
+MyApplication* my_application_new();
+
+#endif // FLUTTER_MY_APPLICATION_H_
diff --git a/examples/platform_view/pubspec.yaml b/examples/platform_view/pubspec.yaml
index d51f59a..6d1111b 100644
--- a/examples/platform_view/pubspec.yaml
+++ b/examples/platform_view/pubspec.yaml
@@ -9,10 +9,10 @@
characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
collection: 1.17.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.9.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
flutter:
@@ -20,4 +20,4 @@
assets:
- assets/flutter-mark-square-64.png
-# PUBSPEC CHECKSUM: 3e9c
+# PUBSPEC CHECKSUM: a9c0
diff --git a/examples/platform_view/windows/flutter/generated_plugins.cmake b/examples/platform_view/windows/flutter/generated_plugins.cmake
deleted file mode 100644
index b93c4c3..0000000
--- a/examples/platform_view/windows/flutter/generated_plugins.cmake
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Generated file, do not edit.
-#
-
-list(APPEND FLUTTER_PLUGIN_LIST
-)
-
-list(APPEND FLUTTER_FFI_PLUGIN_LIST
-)
-
-set(PLUGIN_BUNDLED_LIBRARIES)
-
-foreach(plugin ${FLUTTER_PLUGIN_LIST})
- add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin})
- target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
- list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
- list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
-endforeach(plugin)
-
-foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
- add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin})
- list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
-endforeach(ffi_plugin)
diff --git a/examples/splash/pubspec.yaml b/examples/splash/pubspec.yaml
index 671d11b..864fe34 100644
--- a/examples/splash/pubspec.yaml
+++ b/examples/splash/pubspec.yaml
@@ -9,10 +9,10 @@
characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
collection: 1.17.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.9.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
flutter_test:
@@ -25,10 +25,10 @@
matcher: 0.12.16 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path: 1.8.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
-# PUBSPEC CHECKSUM: d91e
+# PUBSPEC CHECKSUM: 7f45
diff --git a/examples/texture/README.md b/examples/texture/README.md
new file mode 100644
index 0000000..8a46fe3
--- /dev/null
+++ b/examples/texture/README.md
@@ -0,0 +1,3 @@
+# Flutter Texture
+
+An example to show how to use custom Flutter textures.
diff --git a/examples/texture/lib/main.dart b/examples/texture/lib/main.dart
new file mode 100644
index 0000000..2f0cc7e
--- /dev/null
+++ b/examples/texture/lib/main.dart
@@ -0,0 +1,94 @@
+// Copyright 2014 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+
+class TexturePage extends StatefulWidget {
+ const TexturePage({super.key});
+
+ @override
+ State<TexturePage> createState() => _TexturePageState();
+}
+
+class _TexturePageState extends State<TexturePage> {
+ static const int textureWidth = 300;
+ static const int textureHeight = 300;
+ static const MethodChannel channel =
+ MethodChannel('samples.flutter.io/texture');
+ final Future<int?> textureId =
+ channel.invokeMethod('create', <int>[textureWidth, textureHeight]);
+
+ // Set the color of the texture.
+ Future<void> setColor(int r, int g, int b) async {
+ await channel.invokeMethod('setColor', <int>[r, g, b]);
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ backgroundColor: Theme.of(context).colorScheme.inversePrimary,
+ title: const Text('Texture Example'),
+ ),
+ body: Center(
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: <Widget>[
+ FutureBuilder<int?>(
+ future: textureId,
+ builder: (BuildContext context, AsyncSnapshot<int?> snapshot) {
+ if (snapshot.hasData) {
+ if (snapshot.data != null) {
+ return SizedBox(
+ width: textureWidth.toDouble(),
+ height: textureHeight.toDouble(),
+ child: Texture(textureId: snapshot.data!),
+ );
+ } else {
+ return const Text('Error creating texture');
+ }
+ } else {
+ return const Text('Creating texture...');
+ }
+ },
+ ),
+ const SizedBox(height: 10),
+ OutlinedButton(
+ child: const Text('Flutter Navy'),
+ onPressed: () => setColor(0x04, 0x2b, 0x59)),
+ const SizedBox(height: 10),
+ OutlinedButton(
+ child: const Text('Flutter Blue'),
+ onPressed: () => setColor(0x05, 0x53, 0xb1)),
+ const SizedBox(height: 10),
+ OutlinedButton(
+ child: const Text('Flutter Sky'),
+ onPressed: () => setColor(0x02, 0x7d, 0xfd)),
+ const SizedBox(height: 10),
+ OutlinedButton(
+ child: const Text('Red'),
+ onPressed: () => setColor(0xf2, 0x5d, 0x50)),
+ const SizedBox(height: 10),
+ OutlinedButton(
+ child: const Text('Yellow'),
+ onPressed: () => setColor(0xff, 0xf2, 0x75)),
+ const SizedBox(height: 10),
+ OutlinedButton(
+ child: const Text('Purple'),
+ onPressed: () => setColor(0x62, 0x00, 0xee)),
+ const SizedBox(height: 10),
+ OutlinedButton(
+ child: const Text('Green'),
+ onPressed: () => setColor(0x1c, 0xda, 0xc5)),
+ ],
+ ),
+ ),
+ );
+ }
+}
+
+void main() {
+ runApp(const MaterialApp(home: TexturePage()));
+}
diff --git a/examples/texture/linux/CMakeLists.txt b/examples/texture/linux/CMakeLists.txt
new file mode 100644
index 0000000..af26da2
--- /dev/null
+++ b/examples/texture/linux/CMakeLists.txt
@@ -0,0 +1,141 @@
+# Project-level configuration.
+cmake_minimum_required(VERSION 3.10)
+project(runner LANGUAGES CXX)
+set(CMAKE_CXX_STANDARD 17)
+
+# The name of the executable created for the application. Change this to change
+# the on-disk name of your application.
+set(BINARY_NAME "texture")
+# The unique GTK application identifier for this application. See:
+# https://wiki.gnome.org/HowDoI/ChooseApplicationID
+set(APPLICATION_ID "io.flutter.examples.texture")
+
+# Explicitly opt in to modern CMake behaviors to avoid warnings with recent
+# versions of CMake.
+cmake_policy(SET CMP0063 NEW)
+
+# Load bundled libraries from the lib/ directory relative to the binary.
+set(CMAKE_INSTALL_RPATH "$ORIGIN/lib")
+
+# Root filesystem for cross-building.
+if(FLUTTER_TARGET_PLATFORM_SYSROOT)
+ set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT})
+ set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})
+ set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
+ set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+ set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+endif()
+
+# Define build configuration options.
+if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
+ set(CMAKE_BUILD_TYPE "Debug" CACHE
+ STRING "Flutter build mode" FORCE)
+ set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
+ "Debug" "Profile" "Release")
+endif()
+
+# Compilation settings that should be applied to most targets.
+#
+# Be cautious about adding new options here, as plugins use this function by
+# default. In most cases, you should add new options to specific targets instead
+# of modifying this function.
+function(APPLY_STANDARD_SETTINGS TARGET)
+ target_compile_features(${TARGET} PUBLIC cxx_std_14)
+ target_compile_options(${TARGET} PRIVATE -Wall -Werror)
+ target_compile_options(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:-O3>")
+ target_compile_definitions(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:NDEBUG>")
+endfunction()
+
+# Flutter library and tool build rules.
+set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter")
+add_subdirectory(${FLUTTER_MANAGED_DIR})
+
+# System-level dependencies.
+find_package(PkgConfig REQUIRED)
+pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
+
+add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}")
+
+# Define the application target. To change its name, change BINARY_NAME above,
+# not the value here, or `flutter run` will no longer work.
+#
+# Any new source files that you add to the application should be added here.
+add_executable(${BINARY_NAME}
+ "main.cc"
+ "my_application.cc"
+ "my_texture.cc"
+ "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
+)
+
+# Apply the standard set of build settings. This can be removed for applications
+# that need different build settings.
+apply_standard_settings(${BINARY_NAME})
+
+# Add dependency libraries. Add any application-specific dependencies here.
+target_link_libraries(${BINARY_NAME} PRIVATE flutter)
+target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK)
+
+# Run the Flutter tool portions of the build. This must not be removed.
+add_dependencies(${BINARY_NAME} flutter_assemble)
+
+# Only the install-generated bundle's copy of the executable will launch
+# correctly, since the resources must in the right relative locations. To avoid
+# people trying to run the unbundled copy, put it in a subdirectory instead of
+# the default top-level location.
+set_target_properties(${BINARY_NAME}
+ PROPERTIES
+ RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run"
+)
+
+
+# Generated plugin build rules, which manage building the plugins and adding
+# them to the application.
+include(flutter/generated_plugins.cmake)
+
+
+# === Installation ===
+# By default, "installing" just makes a relocatable bundle in the build
+# directory.
+set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle")
+if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
+ set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE)
+endif()
+
+# Start with a clean build bundle directory every time.
+install(CODE "
+ file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\")
+ " COMPONENT Runtime)
+
+set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data")
+set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib")
+
+install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}"
+ COMPONENT Runtime)
+
+install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
+ COMPONENT Runtime)
+
+install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
+ COMPONENT Runtime)
+
+foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES})
+ install(FILES "${bundled_library}"
+ DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
+ COMPONENT Runtime)
+endforeach(bundled_library)
+
+# Fully re-copy the assets directory on each build to avoid having stale files
+# from a previous install.
+set(FLUTTER_ASSET_DIR_NAME "flutter_assets")
+install(CODE "
+ file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\")
+ " COMPONENT Runtime)
+install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}"
+ DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime)
+
+# Install the AOT library on non-Debug builds only.
+if(NOT CMAKE_BUILD_TYPE MATCHES "Debug")
+ install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
+ COMPONENT Runtime)
+endif()
diff --git a/examples/texture/linux/flutter/CMakeLists.txt b/examples/texture/linux/flutter/CMakeLists.txt
new file mode 100644
index 0000000..d5bd016
--- /dev/null
+++ b/examples/texture/linux/flutter/CMakeLists.txt
@@ -0,0 +1,88 @@
+# This file controls Flutter-level build steps. It should not be edited.
+cmake_minimum_required(VERSION 3.10)
+
+set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral")
+
+# Configuration provided via flutter tool.
+include(${EPHEMERAL_DIR}/generated_config.cmake)
+
+# TODO: Move the rest of this into files in ephemeral. See
+# https://github.com/flutter/flutter/issues/57146.
+
+# Serves the same purpose as list(TRANSFORM ... PREPEND ...),
+# which isn't available in 3.10.
+function(list_prepend LIST_NAME PREFIX)
+ set(NEW_LIST "")
+ foreach(element ${${LIST_NAME}})
+ list(APPEND NEW_LIST "${PREFIX}${element}")
+ endforeach(element)
+ set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE)
+endfunction()
+
+# === Flutter Library ===
+# System-level dependencies.
+find_package(PkgConfig REQUIRED)
+pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
+pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0)
+pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0)
+
+set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so")
+
+# Published to parent scope for install step.
+set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE)
+set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE)
+set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE)
+set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE)
+
+list(APPEND FLUTTER_LIBRARY_HEADERS
+ "fl_basic_message_channel.h"
+ "fl_binary_codec.h"
+ "fl_binary_messenger.h"
+ "fl_dart_project.h"
+ "fl_engine.h"
+ "fl_json_message_codec.h"
+ "fl_json_method_codec.h"
+ "fl_message_codec.h"
+ "fl_method_call.h"
+ "fl_method_channel.h"
+ "fl_method_codec.h"
+ "fl_method_response.h"
+ "fl_plugin_registrar.h"
+ "fl_plugin_registry.h"
+ "fl_standard_message_codec.h"
+ "fl_standard_method_codec.h"
+ "fl_string_codec.h"
+ "fl_value.h"
+ "fl_view.h"
+ "flutter_linux.h"
+)
+list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/")
+add_library(flutter INTERFACE)
+target_include_directories(flutter INTERFACE
+ "${EPHEMERAL_DIR}"
+)
+target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}")
+target_link_libraries(flutter INTERFACE
+ PkgConfig::GTK
+ PkgConfig::GLIB
+ PkgConfig::GIO
+)
+add_dependencies(flutter flutter_assemble)
+
+# === Flutter tool backend ===
+# _phony_ is a non-existent file to force this command to run every time,
+# since currently there's no way to get a full input/output list from the
+# flutter tool.
+add_custom_command(
+ OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS}
+ ${CMAKE_CURRENT_BINARY_DIR}/_phony_
+ COMMAND ${CMAKE_COMMAND} -E env
+ ${FLUTTER_TOOL_ENVIRONMENT}
+ "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh"
+ ${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE}
+ VERBATIM
+)
+add_custom_target(flutter_assemble DEPENDS
+ "${FLUTTER_LIBRARY}"
+ ${FLUTTER_LIBRARY_HEADERS}
+)
diff --git a/examples/texture/linux/main.cc b/examples/texture/linux/main.cc
new file mode 100644
index 0000000..281a29e
--- /dev/null
+++ b/examples/texture/linux/main.cc
@@ -0,0 +1,10 @@
+// Copyright 2014 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "my_application.h"
+
+int main(int argc, char** argv) {
+ g_autoptr(MyApplication) app = my_application_new();
+ return g_application_run(G_APPLICATION(app), argc, argv);
+}
diff --git a/examples/texture/linux/my_application.cc b/examples/texture/linux/my_application.cc
new file mode 100644
index 0000000..f46cf9c
--- /dev/null
+++ b/examples/texture/linux/my_application.cc
@@ -0,0 +1,172 @@
+// Copyright 2014 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "my_application.h"
+
+#include <flutter_linux/flutter_linux.h>
+
+#include "my_texture.h"
+#ifdef GDK_WINDOWING_X11
+#include <gdk/gdkx.h>
+#endif
+
+#include "flutter/generated_plugin_registrant.h"
+
+struct _MyApplication {
+ GtkApplication parent_instance;
+
+ // Channel to receive texture requests from Flutter.
+ FlMethodChannel* texture_channel;
+
+ // Texture we've created.
+ MyTexture* texture;
+
+ FlView* view;
+};
+
+G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION)
+
+// Handle request to create the texture.
+static FlMethodResponse* handle_create(MyApplication* self,
+ FlMethodCall* method_call) {
+ if (self->texture != nullptr) {
+ return FL_METHOD_RESPONSE(fl_method_error_response_new(
+ "Error", "texture already created", nullptr));
+ }
+
+ FlValue* args = fl_method_call_get_args(method_call);
+ if (fl_value_get_type(args) != FL_VALUE_TYPE_LIST ||
+ fl_value_get_length(args) != 2) {
+ return FL_METHOD_RESPONSE(fl_method_error_response_new(
+ "Invalid args", "Invalid create args", nullptr));
+ }
+ FlValue* width_value = fl_value_get_list_value(args, 0);
+ FlValue* height_value = fl_value_get_list_value(args, 1);
+ if (fl_value_get_type(width_value) != FL_VALUE_TYPE_INT ||
+ fl_value_get_type(height_value) != FL_VALUE_TYPE_INT) {
+ return FL_METHOD_RESPONSE(fl_method_error_response_new(
+ "Invalid args", "Invalid create args", nullptr));
+ }
+
+ FlEngine* engine = fl_view_get_engine(self->view);
+ FlTextureRegistrar* texture_registrar =
+ fl_engine_get_texture_registrar(engine);
+
+ self->texture =
+ my_texture_new(fl_value_get_int(width_value),
+ fl_value_get_int(height_value), 0x05, 0x53, 0xb1);
+ if (!fl_texture_registrar_register_texture(texture_registrar,
+ FL_TEXTURE(self->texture))) {
+ return FL_METHOD_RESPONSE(fl_method_error_response_new(
+ "Error", "Failed to register texture", nullptr));
+ }
+
+ // Return the texture ID to Flutter so it can use this texture.
+ g_autoptr(FlValue) id =
+ fl_value_new_int(fl_texture_get_id(FL_TEXTURE(self->texture)));
+ return FL_METHOD_RESPONSE(fl_method_success_response_new(id));
+}
+
+// Handle request to set the texture color.
+static FlMethodResponse* handle_set_color(MyApplication* self,
+ FlMethodCall* method_call) {
+ FlValue* args = fl_method_call_get_args(method_call);
+ if (fl_value_get_type(args) != FL_VALUE_TYPE_LIST ||
+ fl_value_get_length(args) != 3) {
+ return FL_METHOD_RESPONSE(fl_method_error_response_new(
+ "Invalid args", "Invalid setColor args", nullptr));
+ }
+ FlValue* r_value = fl_value_get_list_value(args, 0);
+ FlValue* g_value = fl_value_get_list_value(args, 1);
+ FlValue* b_value = fl_value_get_list_value(args, 2);
+ if (fl_value_get_type(r_value) != FL_VALUE_TYPE_INT ||
+ fl_value_get_type(g_value) != FL_VALUE_TYPE_INT ||
+ fl_value_get_type(b_value) != FL_VALUE_TYPE_INT) {
+ return FL_METHOD_RESPONSE(fl_method_error_response_new(
+ "Invalid args", "Invalid setColor args", nullptr));
+ }
+
+ FlEngine* engine = fl_view_get_engine(self->view);
+ FlTextureRegistrar* texture_registrar =
+ fl_engine_get_texture_registrar(engine);
+
+ // Redraw in requested color.
+ my_texture_set_color(self->texture, fl_value_get_int(r_value),
+ fl_value_get_int(g_value), fl_value_get_int(b_value));
+
+ // Notify Flutter the texture has changed.
+ fl_texture_registrar_mark_texture_frame_available(texture_registrar,
+ FL_TEXTURE(self->texture));
+
+ return FL_METHOD_RESPONSE(fl_method_success_response_new(nullptr));
+}
+
+// Handle texture requests from Flutter.
+static void texture_channel_method_cb(FlMethodChannel* channel,
+ FlMethodCall* method_call,
+ gpointer user_data) {
+ MyApplication* self = MY_APPLICATION(user_data);
+
+ const char* name = fl_method_call_get_name(method_call);
+ if (g_str_equal(name, "create")) {
+ g_autoptr(FlMethodResponse) response = handle_create(self, method_call);
+ fl_method_call_respond(method_call, response, NULL);
+ } else if (g_str_equal(name, "setColor")) {
+ g_autoptr(FlMethodResponse) response = handle_set_color(self, method_call);
+ fl_method_call_respond(method_call, response, NULL);
+ } else {
+ fl_method_call_respond_not_implemented(method_call, NULL);
+ }
+}
+
+// Implements GObject::dispose.
+static void my_application_dispose(GObject* object) {
+ MyApplication* self = MY_APPLICATION(object);
+
+ g_clear_object(&self->texture_channel);
+ g_clear_object(&self->texture);
+
+ G_OBJECT_CLASS(my_application_parent_class)->dispose(object);
+}
+
+// Implements GApplication::activate.
+static void my_application_activate(GApplication* application) {
+ MyApplication* self = MY_APPLICATION(application);
+ GtkWindow* window =
+ GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application)));
+
+ gtk_window_set_default_size(window, 1280, 720);
+ gtk_widget_show(GTK_WIDGET(window));
+
+ g_autoptr(FlDartProject) project = fl_dart_project_new();
+ self->view = fl_view_new(project);
+ gtk_widget_show(GTK_WIDGET(self->view));
+ gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(self->view));
+
+ // Create channel to handle texture requests from Flutter.
+ FlEngine* engine = fl_view_get_engine(self->view);
+ g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new();
+ self->texture_channel = fl_method_channel_new(
+ fl_engine_get_binary_messenger(engine), "samples.flutter.io/texture",
+ FL_METHOD_CODEC(codec));
+ fl_method_channel_set_method_call_handler(
+ self->texture_channel, texture_channel_method_cb, self, nullptr);
+
+ fl_register_plugins(FL_PLUGIN_REGISTRY(self->view));
+
+ gtk_widget_grab_focus(GTK_WIDGET(self->view));
+}
+
+static void my_application_class_init(MyApplicationClass* klass) {
+ G_OBJECT_CLASS(klass)->dispose = my_application_dispose;
+ G_APPLICATION_CLASS(klass)->activate = my_application_activate;
+}
+
+static void my_application_init(MyApplication* self) {}
+
+MyApplication* my_application_new() {
+ return MY_APPLICATION(g_object_new(my_application_get_type(),
+ "application-id", APPLICATION_ID, "flags",
+ G_APPLICATION_NON_UNIQUE, nullptr));
+}
diff --git a/examples/texture/linux/my_application.h b/examples/texture/linux/my_application.h
new file mode 100644
index 0000000..8c66ec4
--- /dev/null
+++ b/examples/texture/linux/my_application.h
@@ -0,0 +1,22 @@
+// Copyright 2014 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef FLUTTER_MY_APPLICATION_H_
+#define FLUTTER_MY_APPLICATION_H_
+
+#include <gtk/gtk.h>
+
+G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION,
+ GtkApplication)
+
+/**
+ * my_application_new:
+ *
+ * Creates a new Flutter-based application.
+ *
+ * Returns: a new #MyApplication.
+ */
+MyApplication* my_application_new();
+
+#endif // FLUTTER_MY_APPLICATION_H_
diff --git a/examples/texture/linux/my_texture.cc b/examples/texture/linux/my_texture.cc
new file mode 100644
index 0000000..5690ad0
--- /dev/null
+++ b/examples/texture/linux/my_texture.cc
@@ -0,0 +1,72 @@
+// Copyright 2014 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "my_texture.h"
+
+// An object that generates a texture for Flutter.
+struct _MyTexture {
+ FlPixelBufferTexture parent_instance;
+
+ // Dimensions of texture.
+ uint32_t width;
+ uint32_t height;
+
+ // Buffer used to store texture.
+ uint8_t* buffer;
+};
+
+G_DEFINE_TYPE(MyTexture, my_texture, fl_pixel_buffer_texture_get_type())
+
+// Implements GObject::dispose.
+static void my_texture_dispose(GObject* object) {
+ MyTexture* self = MY_TEXTURE(object);
+
+ free(self->buffer);
+
+ G_OBJECT_CLASS(my_texture_parent_class)->dispose(object);
+}
+
+// Implements FlPixelBufferTexture::copy_pixels.
+static gboolean my_texture_copy_pixels(FlPixelBufferTexture* texture,
+ const uint8_t** out_buffer,
+ uint32_t* width, uint32_t* height,
+ GError** error) {
+ MyTexture* self = MY_TEXTURE(texture);
+ *out_buffer = self->buffer;
+ *width = self->width;
+ *height = self->height;
+ return TRUE;
+}
+
+static void my_texture_class_init(MyTextureClass* klass) {
+ G_OBJECT_CLASS(klass)->dispose = my_texture_dispose;
+ FL_PIXEL_BUFFER_TEXTURE_CLASS(klass)->copy_pixels = my_texture_copy_pixels;
+}
+
+static void my_texture_init(MyTexture* self) {}
+
+MyTexture* my_texture_new(uint32_t width, uint32_t height, uint8_t r, uint8_t g,
+ uint8_t b) {
+ MyTexture* self = MY_TEXTURE(g_object_new(my_texture_get_type(), nullptr));
+ self->width = width;
+ self->height = height;
+ self->buffer = static_cast<uint8_t*>(malloc(self->width * self->height * 4));
+ my_texture_set_color(self, r, g, b);
+ return self;
+}
+
+// Draws the texture with the requested color.
+void my_texture_set_color(MyTexture* self, uint8_t r, uint8_t g, uint8_t b) {
+ g_return_if_fail(MY_IS_TEXTURE(self));
+
+ for (size_t y = 0; y < self->height; y++) {
+ for (size_t x = 0; x < self->width; x++) {
+ uint8_t* pixel = self->buffer + (y * self->width * 4) + (x * 4);
+ pixel[0] = r;
+ pixel[1] = g;
+ pixel[2] = b;
+ pixel[3] = 255;
+ }
+ }
+}
diff --git a/examples/texture/linux/my_texture.h b/examples/texture/linux/my_texture.h
new file mode 100644
index 0000000..2b8cf82
--- /dev/null
+++ b/examples/texture/linux/my_texture.h
@@ -0,0 +1,39 @@
+// Copyright 2014 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef FLUTTER_MY_TEXTURE_H_
+#define FLUTTER_MY_TEXTURE_H_
+
+#include <flutter_linux/flutter_linux.h>
+
+G_DECLARE_FINAL_TYPE(MyTexture, my_texture, MY, TEXTURE, FlPixelBufferTexture)
+
+/**
+ * my_texture_new:
+ * @self: a #MyTexture.
+ * @width: width of texture in pixels.
+ * @height: height of texture in pixels.
+ * @r: red value for texture color.
+ * @g: green value for texture color.
+ * @b: blue value for texture color.
+ *
+ * Creates a new texture containing a single color for Flutter to render with.
+ *
+ * Returns: a new #MyTexture.
+ */
+MyTexture* my_texture_new(uint32_t width, uint32_t height, uint8_t r, uint8_t g,
+ uint8_t b);
+
+/**
+ * my_texture_new:
+ * @self: a #MyTexture.
+ * @r: red value for texture color.
+ * @g: green value for texture color.
+ * @b: blue value for texture color.
+ *
+ * Sets the color the texture contains.
+ */
+void my_texture_set_color(MyTexture* self, uint8_t r, uint8_t g, uint8_t b);
+
+#endif // FLUTTER_MY_TEXTURE_H_
diff --git a/examples/texture/pubspec.yaml b/examples/texture/pubspec.yaml
new file mode 100644
index 0000000..891bf36
--- /dev/null
+++ b/examples/texture/pubspec.yaml
@@ -0,0 +1,68 @@
+name: texture
+
+environment:
+ sdk: '>=3.0.0-0 <4.0.0'
+
+dependencies:
+ flutter:
+ sdk: flutter
+
+ characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ collection: 1.17.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ meta: 1.9.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+
+dev_dependencies:
+ flutter_test:
+ sdk: flutter
+ test: 1.24.4
+
+ _fe_analyzer_shared: 62.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ analyzer: 6.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ args: 2.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ async: 2.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ clock: 1.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ convert: 3.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ coverage: 1.6.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ crypto: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ dart_internal: 0.2.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ fake_async: 1.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ file: 6.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ frontend_server_client: 3.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ glob: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ http_multi_server: 3.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ http_parser: 4.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ io: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ logging: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ matcher: 0.12.16 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ mime: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ node_preamble: 2.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ package_config: 2.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ path: 1.8.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ pool: 1.5.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ pub_semver: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ shelf: 1.4.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ shelf_packages_handler: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ shelf_static: 1.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ shelf_web_socket: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ source_map_stack_trace: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ source_maps: 0.10.12 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_core: 0.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ vm_service: 11.7.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ webkit_inspection_protocol: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+
+# PUBSPEC CHECKSUM: 79da
diff --git a/examples/texture/test/texture_test.dart b/examples/texture/test/texture_test.dart
new file mode 100644
index 0000000..bd8faa9
--- /dev/null
+++ b/examples/texture/test/texture_test.dart
@@ -0,0 +1,16 @@
+// Copyright 2014 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'package:flutter_test/flutter_test.dart';
+import 'package:texture/main.dart' as texture;
+
+void main() {
+ testWidgets('Texture smoke test', (WidgetTester tester) async {
+ texture
+ .main(); // builds the app and schedules a frame but doesn't trigger one
+ await tester.pump(); // triggers a frame
+
+ expect(find.text('Fluter Blue'), findsOneWidget);
+ });
+}
diff --git a/packages/flutter/lib/fix_data/fix_services.yaml b/packages/flutter/lib/fix_data/fix_services.yaml
index b409e6c..35c8a23 100644
--- a/packages/flutter/lib/fix_data/fix_services.yaml
+++ b/packages/flutter/lib/fix_data/fix_services.yaml
@@ -18,6 +18,20 @@
# * Fixes in this file are from the Services library. *
version: 1
transforms:
+ # Changes made in https://github.com/flutter/flutter/pull/122446
+ - title: "Migrate to empty 'text' string"
+ date: 2023-06-26
+ element:
+ uris: [ 'services.dart' ]
+ constructor: ''
+ inClass: 'ClipboardData'
+ changes:
+ - kind: 'changeParameterType'
+ name: 'text'
+ nullability: 'non_null'
+ argumentValue:
+ expression: "''"
+
# Changes made in https://github.com/flutter/flutter/pull/60320
- title: "Migrate to 'viewId'"
date: 2020-07-05
diff --git a/packages/flutter/lib/foundation.dart b/packages/flutter/lib/foundation.dart
index dff7553..43ac813 100644
--- a/packages/flutter/lib/foundation.dart
+++ b/packages/flutter/lib/foundation.dart
@@ -46,4 +46,5 @@
export 'src/foundation/service_extensions.dart';
export 'src/foundation/stack_frame.dart';
export 'src/foundation/synchronous_future.dart';
+export 'src/foundation/timeline.dart';
export 'src/foundation/unicode.dart';
diff --git a/packages/flutter/lib/material.dart b/packages/flutter/lib/material.dart
index 8ca80a7..213bd29 100644
--- a/packages/flutter/lib/material.dart
+++ b/packages/flutter/lib/material.dart
@@ -10,14 +10,10 @@
///
/// See also:
///
-/// * [flutter.dev/widgets/material](https://flutter.dev/widgets/material)
+/// * [docs.flutter.dev/ui/widgets/material](https://docs.flutter.dev/ui/widgets/material)
/// for a catalog of commonly-used Material component widgets.
-/// * [material.io/design](https://material.io/design/)
-/// for an introduction to Material Design.
-/// * [material.io/components](https://material.io/components?platform=flutter)
-/// for the Material 2 specification.
-/// * [m3.material.io](https://m3.material.io)
-/// for the Material 3 specification.
+/// * [m3.material.io](https://m3.material.io/) for the Material 3 specification
+/// * [m2.material.io](https://m2.material.io/) for the Material 2 specification
library material;
export 'src/material/about.dart';
diff --git a/packages/flutter/lib/rendering.dart b/packages/flutter/lib/rendering.dart
index 4b47bc1..20705ce 100644
--- a/packages/flutter/lib/rendering.dart
+++ b/packages/flutter/lib/rendering.dart
@@ -37,6 +37,7 @@
export 'src/rendering/custom_paint.dart';
export 'src/rendering/debug.dart';
export 'src/rendering/debug_overflow_indicator.dart';
+export 'src/rendering/decorated_sliver.dart';
export 'src/rendering/editable.dart';
export 'src/rendering/error.dart';
export 'src/rendering/flex.dart';
diff --git a/packages/flutter/lib/services.dart b/packages/flutter/lib/services.dart
index 9bca453..9cfde5e 100644
--- a/packages/flutter/lib/services.dart
+++ b/packages/flutter/lib/services.dart
@@ -25,6 +25,7 @@
export 'src/services/keyboard_inserted_content.dart';
export 'src/services/keyboard_key.g.dart';
export 'src/services/keyboard_maps.g.dart';
+export 'src/services/live_text.dart';
export 'src/services/message_codec.dart';
export 'src/services/message_codecs.dart';
export 'src/services/mouse_cursor.dart';
diff --git a/packages/flutter/lib/src/cupertino/adaptive_text_selection_toolbar.dart b/packages/flutter/lib/src/cupertino/adaptive_text_selection_toolbar.dart
index 19302c2..33f5e50 100644
--- a/packages/flutter/lib/src/cupertino/adaptive_text_selection_toolbar.dart
+++ b/packages/flutter/lib/src/cupertino/adaptive_text_selection_toolbar.dart
@@ -94,6 +94,7 @@
required VoidCallback? onCut,
required VoidCallback? onPaste,
required VoidCallback? onSelectAll,
+ required VoidCallback? onLiveTextInput,
required this.anchors,
}) : children = null,
buttonItems = EditableText.getEditableButtonItems(
@@ -102,6 +103,7 @@
onCut: onCut,
onPaste: onPaste,
onSelectAll: onSelectAll,
+ onLiveTextInput: onLiveTextInput
);
/// Create an instance of [CupertinoAdaptiveTextSelectionToolbar] with the
diff --git a/packages/flutter/lib/src/cupertino/dialog.dart b/packages/flutter/lib/src/cupertino/dialog.dart
index 1f9e0e9..0cb4cf8 100644
--- a/packages/flutter/lib/src/cupertino/dialog.dart
+++ b/packages/flutter/lib/src/cupertino/dialog.dart
@@ -1556,7 +1556,7 @@
parentData.isPressed = isPressed;
// Force a repaint.
- final AbstractNode? targetParent = renderObject.parent;
+ final RenderObject? targetParent = renderObject.parent;
if (targetParent is RenderObject) {
targetParent.markNeedsPaint();
}
diff --git a/packages/flutter/lib/src/cupertino/switch.dart b/packages/flutter/lib/src/cupertino/switch.dart
index 2057e11..75518bc 100644
--- a/packages/flutter/lib/src/cupertino/switch.dart
+++ b/packages/flutter/lib/src/cupertino/switch.dart
@@ -75,6 +75,8 @@
this.thumbColor,
this.applyTheme,
this.focusColor,
+ this.onLabelColor,
+ this.offLabelColor,
this.focusNode,
this.onFocusChange,
this.autofocus = false,
@@ -133,6 +135,17 @@
/// Defaults to a slightly transparent [activeColor].
final Color? focusColor;
+ /// The color to use for the accessibility label when the switch is on.
+ ///
+ /// Defaults to [CupertinoColors.white] when null.
+ final Color? onLabelColor;
+
+ /// The color to use for the accessibility label when the switch is off.
+ ///
+ /// Defaults to [Color.fromARGB(255, 179, 179, 179)]
+ /// (or [Color.fromARGB(255, 255, 255, 255)] in high contrast) when null.
+ final Color? offLabelColor;
+
/// {@macro flutter.widgets.Focus.focusNode}
final FocusNode? focusNode;
@@ -357,6 +370,19 @@
?? CupertinoColors.systemGreen,
context,
);
+ final (Color onLabelColor, Color offLabelColor)? onOffLabelColors =
+ MediaQuery.onOffSwitchLabelsOf(context)
+ ? (
+ CupertinoDynamicColor.resolve(
+ widget.onLabelColor ?? CupertinoColors.white,
+ context,
+ ),
+ CupertinoDynamicColor.resolve(
+ widget.offLabelColor ?? _kOffLabelColor,
+ context,
+ ),
+ )
+ : null;
if (needsPositionAnimation) {
_resumePositionAnimation();
}
@@ -389,6 +415,7 @@
textDirection: Directionality.of(context),
isFocused: isFocused,
state: this,
+ onOffLabelColors: onOffLabelColors,
),
),
),
@@ -417,6 +444,7 @@
required this.textDirection,
required this.isFocused,
required this.state,
+ required this.onOffLabelColors,
});
final bool value;
@@ -428,6 +456,7 @@
final _CupertinoSwitchState state;
final TextDirection textDirection;
final bool isFocused;
+ final (Color onLabelColor, Color offLabelColor)? onOffLabelColors;
@override
_RenderCupertinoSwitch createRenderObject(BuildContext context) {
@@ -441,6 +470,7 @@
textDirection: textDirection,
isFocused: isFocused,
state: state,
+ onOffLabelColors: onOffLabelColors,
);
}
@@ -467,6 +497,24 @@
const double _kTrackInnerLength = _kTrackInnerEnd - _kTrackInnerStart;
const double _kSwitchWidth = 59.0;
const double _kSwitchHeight = 39.0;
+// Label sizes and padding taken from xcode inspector.
+// See https://github.com/flutter/flutter/issues/4830#issuecomment-528495360
+const double _kOnLabelWidth = 1.0;
+const double _kOnLabelHeight = 10.0;
+const double _kOnLabelPaddingHorizontal = 11.0;
+const double _kOffLabelWidth = 1.0;
+const double _kOffLabelPaddingHorizontal = 12.0;
+const double _kOffLabelRadius = 5.0;
+const CupertinoDynamicColor _kOffLabelColor = CupertinoDynamicColor.withBrightnessAndContrast(
+ debugLabel: 'offSwitchLabel',
+ // Source: https://github.com/flutter/flutter/pull/39993#discussion_r321946033
+ color: Color.fromARGB(255, 179, 179, 179),
+ // Source: https://github.com/flutter/flutter/pull/39993#issuecomment-535196665
+ darkColor: Color.fromARGB(255, 179, 179, 179),
+ // Source: https://github.com/flutter/flutter/pull/127776#discussion_r1244208264
+ highContrastColor: Color.fromARGB(255, 255, 255, 255),
+ darkHighContrastColor: Color.fromARGB(255, 255, 255, 255),
+);
// Opacity of a disabled switch, as eye-balled from iOS Simulator on Mac.
const double _kCupertinoSwitchDisabledOpacity = 0.5;
@@ -484,6 +532,7 @@
required TextDirection textDirection,
required bool isFocused,
required _CupertinoSwitchState state,
+ required (Color onLabelColor, Color offLabelColor)? onOffLabelColors,
}) : _value = value,
_activeColor = activeColor,
_trackColor = trackColor,
@@ -493,6 +542,7 @@
_textDirection = textDirection,
_isFocused = isFocused,
_state = state,
+ _onOffLabelColors = onOffLabelColors,
super(additionalConstraints: const BoxConstraints.tightFor(width: _kSwitchWidth, height: _kSwitchHeight)) {
state.position.addListener(markNeedsPaint);
state._reaction.addListener(markNeedsPaint);
@@ -584,6 +634,16 @@
markNeedsPaint();
}
+ (Color onLabelColor, Color offLabelColor)? get onOffLabelColors => _onOffLabelColors;
+ (Color onLabelColor, Color offLabelColor)? _onOffLabelColors;
+ set onOffLabelColors((Color onLabelColor, Color offLabelColor)? value) {
+ if (value == _onOffLabelColors) {
+ return;
+ }
+ _onOffLabelColors = value;
+ markNeedsPaint();
+ }
+
bool get isInteractive => onChanged != null;
@override
@@ -649,6 +709,52 @@
canvas.drawRRect(borderTrackRRect, borderPaint);
}
+ if (_onOffLabelColors != null) {
+ final (Color onLabelColor, Color offLabelColor) = onOffLabelColors!;
+
+ final double leftLabelOpacity = visualPosition * (1.0 - currentReactionValue);
+ final double rightLabelOpacity = (1.0 - visualPosition) * (1.0 - currentReactionValue);
+ final (double onLabelOpacity, double offLabelOpacity) =
+ switch (textDirection) {
+ TextDirection.ltr => (leftLabelOpacity, rightLabelOpacity),
+ TextDirection.rtl => (rightLabelOpacity, leftLabelOpacity),
+ };
+
+ final (Offset onLabelOffset, Offset offLabelOffset) =
+ switch (textDirection) {
+ TextDirection.ltr => (
+ trackRect.centerLeft.translate(_kOnLabelPaddingHorizontal, 0),
+ trackRect.centerRight.translate(-_kOffLabelPaddingHorizontal, 0),
+ ),
+ TextDirection.rtl => (
+ trackRect.centerRight.translate(-_kOnLabelPaddingHorizontal, 0),
+ trackRect.centerLeft.translate(_kOffLabelPaddingHorizontal, 0),
+ ),
+ };
+
+ // Draws '|' label
+ final Rect onLabelRect = Rect.fromCenter(
+ center: onLabelOffset,
+ width: _kOnLabelWidth,
+ height: _kOnLabelHeight,
+ );
+ final Paint onLabelPaint = Paint()
+ ..color = onLabelColor.withOpacity(onLabelOpacity)
+ ..style = PaintingStyle.fill;
+ canvas.drawRect(onLabelRect, onLabelPaint);
+
+ // Draws 'O' label
+ final Paint offLabelPaint = Paint()
+ ..color = offLabelColor.withOpacity(offLabelOpacity)
+ ..style = PaintingStyle.stroke
+ ..strokeWidth = _kOffLabelWidth;
+ canvas.drawCircle(
+ offLabelOffset,
+ _kOffLabelRadius,
+ offLabelPaint,
+ );
+ }
+
final double currentThumbExtension = CupertinoThumbPainter.extension * currentReactionValue;
final double thumbLeft = lerpDouble(
trackRect.left + _kTrackInnerStart - CupertinoThumbPainter.radius,
diff --git a/packages/flutter/lib/src/cupertino/text_selection_toolbar.dart b/packages/flutter/lib/src/cupertino/text_selection_toolbar.dart
index 9ff7dfc..e4703a6 100644
--- a/packages/flutter/lib/src/cupertino/text_selection_toolbar.dart
+++ b/packages/flutter/lib/src/cupertino/text_selection_toolbar.dart
@@ -15,7 +15,7 @@
// Values extracted from https://developer.apple.com/design/resources/.
// The height of the toolbar, including the arrow.
-const double _kToolbarHeight = 43.0;
+const double _kToolbarHeight = 45.0;
// Vertical distance between the tip of the arrow and the line of text the arrow
// is pointing to. The value used here is eyeballed.
const double _kToolbarContentDistance = 8.0;
@@ -28,15 +28,29 @@
// Values extracted from https://developer.apple.com/design/resources/.
const Radius _kToolbarBorderRadius = Radius.circular(8);
-const CupertinoDynamicColor _kToolbarDividerColor = CupertinoDynamicColor.withBrightness(
- // This value was extracted from a screenshot of iOS 16.0.3, as light mode
- // didn't appear in the Apple design resources assets linked below.
- color: Color(0xFFB6B6B6),
- // Color extracted from https://developer.apple.com/design/resources/.
- // TODO(LongCatIsLooong): https://github.com/flutter/flutter/issues/41507.
- darkColor: Color(0xFF808080),
+// Color was measured from a screenshot of iOS 16.0.2
+// TODO(LongCatIsLooong): https://github.com/flutter/flutter/issues/41507.
+const CupertinoDynamicColor _kToolbarBackgroundColor = CupertinoDynamicColor.withBrightness(
+ color: Color(0xFFF6F6F6),
+ darkColor: Color(0xFF222222),
);
+const double _kToolbarChevronSize = 10;
+const double _kToolbarChevronThickness = 2;
+
+// Color was measured from a screenshot of iOS 16.0.2.
+const CupertinoDynamicColor _kToolbarDividerColor = CupertinoDynamicColor.withBrightness(
+ color: Color(0xFFD6D6D6),
+ darkColor: Color(0xFF424242),
+);
+
+const CupertinoDynamicColor _kToolbarTextColor = CupertinoDynamicColor.withBrightness(
+ color: CupertinoColors.black,
+ darkColor: CupertinoColors.white,
+);
+
+const Duration _kToolbarTransitionDuration = Duration(milliseconds: 125);
+
/// The type for a Function that builds a toolbar's container with the given
/// child.
///
@@ -54,13 +68,6 @@
Widget child,
);
-class _CupertinoToolbarButtonDivider extends StatelessWidget {
- @override
- Widget build(BuildContext context) {
- return SizedBox(width: 1.0 / MediaQuery.devicePixelRatioOf(context));
- }
-}
-
/// An iOS-style text selection toolbar.
///
/// Typically displays buttons for text manipulation, e.g. copying and pasting
@@ -117,29 +124,14 @@
/// * [TextSelectionToolbar], which uses this same value as well.
static const double kToolbarScreenPadding = 8.0;
- // Add the visual vertical line spacer between children buttons.
- static List<Widget> _addChildrenSpacers(List<Widget> children) {
- final List<Widget> nextChildren = <Widget>[];
- for (int i = 0; i < children.length; i++) {
- final Widget child = children[i];
- if (i != 0) {
- nextChildren.add(_CupertinoToolbarButtonDivider());
- }
- nextChildren.add(child);
- }
- return nextChildren;
- }
-
// Builds a toolbar just like the default iOS toolbar, with the right color
// background and a rounded cutout with an arrow.
static Widget _defaultToolbarBuilder(BuildContext context, Offset anchor, bool isAbove, Widget child) {
final Widget outputChild = _CupertinoTextSelectionToolbarShape(
anchor: anchor,
isAbove: isAbove,
- child: DecoratedBox(
- decoration: BoxDecoration(
- color: _kToolbarDividerColor.resolveFrom(context),
- ),
+ child: ColoredBox(
+ color: _kToolbarBackgroundColor.resolveFrom(context),
child: child,
),
);
@@ -209,7 +201,7 @@
anchor: fitsAbove ? anchorAboveAdjusted : anchorBelowAdjusted,
isAbove: fitsAbove,
toolbarBuilder: toolbarBuilder,
- children: _addChildrenSpacers(children),
+ children: children,
),
),
);
@@ -449,19 +441,43 @@
class _CupertinoTextSelectionToolbarContentState extends State<_CupertinoTextSelectionToolbarContent> with TickerProviderStateMixin {
// Controls the fading of the buttons within the menu during page transitions.
late AnimationController _controller;
- int _page = 0;
int? _nextPage;
+ int _page = 0;
+
+ final GlobalKey _toolbarItemsKey = GlobalKey();
+
+ void _onHorizontalDragEnd(DragEndDetails details) {
+ final double? velocity = details.primaryVelocity;
+
+ if (velocity != null && velocity != 0) {
+ if (velocity > 0) {
+ _handlePreviousPage();
+ } else {
+ _handleNextPage();
+ }
+ }
+ }
void _handleNextPage() {
- _controller.reverse();
- _controller.addStatusListener(_statusListener);
- _nextPage = _page + 1;
+ final RenderBox? renderToolbar =
+ _toolbarItemsKey.currentContext?.findRenderObject() as RenderBox?;
+
+ if (renderToolbar is _RenderCupertinoTextSelectionToolbarItems && renderToolbar.hasNextPage) {
+ _controller.reverse();
+ _controller.addStatusListener(_statusListener);
+ _nextPage = _page + 1;
+ }
}
void _handlePreviousPage() {
- _controller.reverse();
- _controller.addStatusListener(_statusListener);
- _nextPage = _page - 1;
+ final RenderBox? renderToolbar =
+ _toolbarItemsKey.currentContext?.findRenderObject() as RenderBox?;
+
+ if (renderToolbar is _RenderCupertinoTextSelectionToolbarItems && renderToolbar.hasPreviousPage) {
+ _controller.reverse();
+ _controller.addStatusListener(_statusListener);
+ _nextPage = _page - 1;
+ }
}
void _statusListener(AnimationStatus status) {
@@ -484,7 +500,7 @@
value: 1.0,
vsync: this,
// This was eyeballed on a physical iOS device running iOS 13.
- duration: const Duration(milliseconds: 150),
+ duration: _kToolbarTransitionDuration,
);
}
@@ -506,53 +522,137 @@
super.dispose();
}
+ Widget _createChevron({required bool isLeft}) {
+ final Color color = _kToolbarTextColor.resolveFrom(context);
+
+ return IgnorePointer(
+ child: Center(
+ // If widthFactor is not set to 0, the button is given unbounded width.
+ widthFactor: 0,
+ child: CustomPaint(
+ painter: isLeft
+ ? _LeftCupertinoChevronPainter(color: color)
+ : _RightCupertinoChevronPainter(color: color),
+ size: const Size.square(_kToolbarChevronSize),
+ ),
+ ),
+ );
+ }
+
@override
Widget build(BuildContext context) {
return widget.toolbarBuilder(context, widget.anchor, widget.isAbove, FadeTransition(
opacity: _controller,
- child: _CupertinoTextSelectionToolbarItems(
- page: _page,
- backButton: CupertinoTextSelectionToolbarButton.text(
- onPressed: _handlePreviousPage,
- text: '◀',
+ child: AnimatedSize(
+ duration: _kToolbarTransitionDuration,
+ curve: Curves.decelerate,
+ child: GestureDetector(
+ onHorizontalDragEnd: _onHorizontalDragEnd,
+ child: _CupertinoTextSelectionToolbarItems(
+ key: _toolbarItemsKey,
+ page: _page,
+ backButton: CupertinoTextSelectionToolbarButton(
+ onPressed: _handlePreviousPage,
+ child: _createChevron(isLeft: true),
+ ),
+ dividerColor: _kToolbarDividerColor.resolveFrom(context),
+ dividerWidth: 1.0 / MediaQuery.devicePixelRatioOf(context),
+ nextButton: CupertinoTextSelectionToolbarButton(
+ onPressed: _handleNextPage,
+ child: _createChevron(isLeft: false),
+ ),
+ children: widget.children,
+ ),
),
- dividerWidth: 1.0 / MediaQuery.devicePixelRatioOf(context),
- nextButton: CupertinoTextSelectionToolbarButton.text(
- onPressed: _handleNextPage,
- text: '▶',
- ),
- nextButtonDisabled: const CupertinoTextSelectionToolbarButton.text(
- text: '▶',
- ),
- children: widget.children,
),
));
}
}
+// These classes help to test the chevrons. As _CupertinoChevronPainter must be
+// private, it's possible to check the runtimeType of each chevron to know if
+// they should be pointing left or right.
+class _LeftCupertinoChevronPainter extends _CupertinoChevronPainter {
+ _LeftCupertinoChevronPainter({required super.color}) : super(isLeft: true);
+}
+class _RightCupertinoChevronPainter extends _CupertinoChevronPainter {
+ _RightCupertinoChevronPainter({required super.color}) : super(isLeft: false);
+}
+abstract class _CupertinoChevronPainter extends CustomPainter {
+ _CupertinoChevronPainter({
+ required this.color,
+ required this.isLeft,
+ });
+
+ final Color color;
+
+ /// If this is true the chevron will point left, else it will point right.
+ final bool isLeft;
+
+ @override
+ void paint(Canvas canvas, Size size) {
+ assert(size.height == size.width, 'size must have the same height and width');
+
+ final double iconSize = size.height;
+
+ // The chevron is half of a square rotated 45˚, so it needs a margin of 1/4
+ // its size on each side to be centered horizontally.
+ //
+ // If pointing left, it means the left half of a square is being used and
+ // the offset is positive. If pointing right, the right half is being used
+ // and the offset is negative.
+ final Offset centerOffset = Offset(
+ iconSize / 4 * (isLeft ? 1 : -1),
+ 0,
+ );
+
+ final Offset firstPoint = Offset(iconSize / 2, 0) + centerOffset;
+ final Offset middlePoint = Offset(isLeft ? 0 : iconSize, iconSize / 2) + centerOffset;
+ final Offset lowerPoint = Offset(iconSize / 2, iconSize) + centerOffset;
+
+ final Paint paint = Paint()
+ ..color = color
+ ..style = PaintingStyle.stroke
+ ..strokeWidth = _kToolbarChevronThickness
+ ..strokeCap = StrokeCap.round
+ ..strokeJoin = StrokeJoin.round;
+
+ // `drawLine` is used here because it's testable. When using `drawPath`,
+ // there's no way to test that the chevron points to the correct side.
+ canvas.drawLine(firstPoint, middlePoint, paint);
+ canvas.drawLine(middlePoint, lowerPoint, paint);
+ }
+
+ @override
+ bool shouldRepaint(_CupertinoChevronPainter oldDelegate) =>
+ oldDelegate.color != color || oldDelegate.isLeft != isLeft;
+}
+
// The custom RenderObjectWidget that, together with
// _RenderCupertinoTextSelectionToolbarItems and
// _CupertinoTextSelectionToolbarItemsElement, paginates the menu items.
class _CupertinoTextSelectionToolbarItems extends RenderObjectWidget {
_CupertinoTextSelectionToolbarItems({
+ super.key,
required this.page,
required this.children,
required this.backButton,
+ required this.dividerColor,
required this.dividerWidth,
required this.nextButton,
- required this.nextButtonDisabled,
}) : assert(children.isNotEmpty);
final Widget backButton;
final List<Widget> children;
+ final Color dividerColor;
final double dividerWidth;
final Widget nextButton;
- final Widget nextButtonDisabled;
final int page;
@override
_RenderCupertinoTextSelectionToolbarItems createRenderObject(BuildContext context) {
return _RenderCupertinoTextSelectionToolbarItems(
+ dividerColor: dividerColor,
dividerWidth: dividerWidth,
page: page,
);
@@ -562,6 +662,7 @@
void updateRenderObject(BuildContext context, _RenderCupertinoTextSelectionToolbarItems renderObject) {
renderObject
..page = page
+ ..dividerColor = dividerColor
..dividerWidth = dividerWidth;
}
@@ -591,8 +692,6 @@
renderObject.backButton = child;
case _CupertinoTextSelectionToolbarItemsSlot.nextButton:
renderObject.nextButton = child;
- case _CupertinoTextSelectionToolbarItemsSlot.nextButtonDisabled:
- renderObject.nextButtonDisabled = child;
}
}
@@ -683,7 +782,6 @@
final _CupertinoTextSelectionToolbarItems toolbarItems = widget as _CupertinoTextSelectionToolbarItems;
_mountChild(toolbarItems.backButton, _CupertinoTextSelectionToolbarItemsSlot.backButton);
_mountChild(toolbarItems.nextButton, _CupertinoTextSelectionToolbarItemsSlot.nextButton);
- _mountChild(toolbarItems.nextButtonDisabled, _CupertinoTextSelectionToolbarItemsSlot.nextButtonDisabled);
// Mount list children.
_children = List<Element>.filled(toolbarItems.children.length, _NullElement.instance);
@@ -718,7 +816,6 @@
final _CupertinoTextSelectionToolbarItems toolbarItems = widget as _CupertinoTextSelectionToolbarItems;
_mountChild(toolbarItems.backButton, _CupertinoTextSelectionToolbarItemsSlot.backButton);
_mountChild(toolbarItems.nextButton, _CupertinoTextSelectionToolbarItemsSlot.nextButton);
- _mountChild(toolbarItems.nextButtonDisabled, _CupertinoTextSelectionToolbarItemsSlot.nextButtonDisabled);
// Update list children.
_children = updateChildren(_children, toolbarItems.children, forgottenChildren: _forgottenChildren);
@@ -729,14 +826,19 @@
// The custom RenderBox that helps paginate the menu items.
class _RenderCupertinoTextSelectionToolbarItems extends RenderBox with ContainerRenderObjectMixin<RenderBox, ToolbarItemsParentData>, RenderBoxContainerDefaultsMixin<RenderBox, ToolbarItemsParentData> {
_RenderCupertinoTextSelectionToolbarItems({
+ required Color dividerColor,
required double dividerWidth,
required int page,
- }) : _dividerWidth = dividerWidth,
+ }) : _dividerColor = dividerColor,
+ _dividerWidth = dividerWidth,
_page = page,
super();
final Map<_CupertinoTextSelectionToolbarItemsSlot, RenderBox> slottedChildren = <_CupertinoTextSelectionToolbarItemsSlot, RenderBox>{};
+ late bool hasNextPage;
+ late bool hasPreviousPage;
+
RenderBox? _updateChild(RenderBox? oldChild, RenderBox? newChild, _CupertinoTextSelectionToolbarItemsSlot slot) {
if (oldChild != null) {
dropChild(oldChild);
@@ -750,7 +852,7 @@
}
bool _isSlottedChild(RenderBox child) {
- return child == _backButton || child == _nextButton || child == _nextButtonDisabled;
+ return child == _backButton || child == _nextButton;
}
int _page;
@@ -763,6 +865,16 @@
markNeedsLayout();
}
+ Color _dividerColor;
+ Color get dividerColor => _dividerColor;
+ set dividerColor(Color value) {
+ if (value == _dividerColor) {
+ return;
+ }
+ _dividerColor = value;
+ markNeedsLayout();
+ }
+
double _dividerWidth;
double get dividerWidth => _dividerWidth;
set dividerWidth(double value) {
@@ -785,12 +897,6 @@
_nextButton = _updateChild(_nextButton, value, _CupertinoTextSelectionToolbarItemsSlot.nextButton);
}
- RenderBox? _nextButtonDisabled;
- RenderBox? get nextButtonDisabled => _nextButtonDisabled;
- set nextButtonDisabled(RenderBox? value) {
- _nextButtonDisabled = _updateChild(_nextButtonDisabled, value, _CupertinoTextSelectionToolbarItemsSlot.nextButtonDisabled);
- }
-
@override
void performLayout() {
if (firstChild == null) {
@@ -801,7 +907,6 @@
// Layout slotted children.
_backButton!.layout(constraints.loosen(), parentUsesSize: true);
_nextButton!.layout(constraints.loosen(), parentUsesSize: true);
- _nextButtonDisabled!.layout(constraints.loosen(), parentUsesSize: true);
final double subsequentPageButtonsWidth =
_backButton!.size.width + _nextButton!.size.width;
@@ -828,7 +933,7 @@
// If this is the last child, it's ok to fit without a forward button.
// Note childCount doesn't include slotted children which come before the list ones.
paginationButtonsWidth =
- i == childCount + 2 ? 0.0 : _nextButton!.size.width;
+ i == childCount + 1 ? 0.0 : _nextButton!.size.width;
} else {
paginationButtonsWidth = subsequentPageButtonsWidth;
}
@@ -881,17 +986,10 @@
if (currentPage > 0) {
final ToolbarItemsParentData nextButtonParentData =
_nextButton!.parentData! as ToolbarItemsParentData;
- final ToolbarItemsParentData nextButtonDisabledParentData =
- _nextButtonDisabled!.parentData! as ToolbarItemsParentData;
final ToolbarItemsParentData backButtonParentData =
_backButton!.parentData! as ToolbarItemsParentData;
- // The forward button always shows if there is more than one page, even on
- // the last page (it's just disabled).
- if (page == currentPage) {
- nextButtonDisabledParentData.offset = Offset(toolbarWidth, 0.0);
- nextButtonDisabledParentData.shouldPaint = true;
- toolbarWidth += nextButtonDisabled!.size.width;
- } else {
+ // The forward button only shows when there's a page after this one.
+ if (page != currentPage) {
nextButtonParentData.offset = Offset(toolbarWidth, 0.0);
nextButtonParentData.shouldPaint = true;
toolbarWidth += nextButton!.size.width;
@@ -903,6 +1001,11 @@
// already been taken care of when laying out the children to
// accommodate the back button.
}
+
+ // Update previous/next page values so that we can check in the horizontal
+ // drag gesture callback if it's possible to navigate.
+ hasNextPage = page != currentPage;
+ hasPreviousPage = page > 0;
} else {
// No divider for the next button when there's only one page.
toolbarWidth -= dividerWidth;
@@ -920,6 +1023,18 @@
if (childParentData.shouldPaint) {
final Offset childOffset = childParentData.offset + offset;
context.paintChild(child, childOffset);
+
+ // backButton is a slotted child and is not in the children list, so its
+ // childParentData.nextSibling is null. So either when there's a
+ // nextSibling or when child is the backButton, draw a divider to the
+ // child's right.
+ if (childParentData.nextSibling != null || child == backButton) {
+ context.canvas.drawLine(
+ Offset(child.size.width, 0) + childOffset,
+ Offset(child.size.width, child.size.height) + childOffset,
+ Paint()..color = dividerColor,
+ );
+ }
}
});
}
@@ -977,9 +1092,6 @@
if (hitTestChild(nextButton, result, position: position)) {
return true;
}
- if (hitTestChild(nextButtonDisabled, result, position: position)) {
- return true;
- }
return false;
}
@@ -1023,9 +1135,6 @@
if (_nextButton != null) {
visitor(_nextButton!);
}
- if (_nextButtonDisabled != null) {
- visitor(_nextButtonDisabled!);
- }
// Visit the list children.
super.visitChildren(visitor);
}
@@ -1051,8 +1160,6 @@
value.add(child.toDiagnosticsNode(name: 'back button'));
} else if (child == nextButton) {
value.add(child.toDiagnosticsNode(name: 'next button'));
- } else if (child == nextButtonDisabled) {
- value.add(child.toDiagnosticsNode(name: 'next button disabled'));
// List children.
} else {
@@ -1068,7 +1175,6 @@
enum _CupertinoTextSelectionToolbarItemsSlot {
backButton,
nextButton,
- nextButtonDisabled,
}
class _NullElement extends Element {
diff --git a/packages/flutter/lib/src/cupertino/text_selection_toolbar_button.dart b/packages/flutter/lib/src/cupertino/text_selection_toolbar_button.dart
index 2d547df..f07d88e 100644
--- a/packages/flutter/lib/src/cupertino/text_selection_toolbar_button.dart
+++ b/packages/flutter/lib/src/cupertino/text_selection_toolbar_button.dart
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+import 'dart:math';
+
import 'package:flutter/widgets.dart';
import 'button.dart';
@@ -11,30 +13,26 @@
const TextStyle _kToolbarButtonFontStyle = TextStyle(
inherit: false,
- fontSize: 14.0,
+ fontSize: 15.0,
letterSpacing: -0.15,
fontWeight: FontWeight.w400,
);
-// Colors extracted from https://developer.apple.com/design/resources/.
-// TODO(LongCatIsLooong): https://github.com/flutter/flutter/issues/41507.
-const CupertinoDynamicColor _kToolbarBackgroundColor = CupertinoDynamicColor.withBrightness(
- // This value was extracted from a screenshot of iOS 16.0.3, as light mode
- // didn't appear in the Apple design resources assets linked above.
- color: Color(0xEBF7F7F7),
- darkColor: Color(0xEB202020),
-);
-
const CupertinoDynamicColor _kToolbarTextColor = CupertinoDynamicColor.withBrightness(
color: CupertinoColors.black,
darkColor: CupertinoColors.white,
);
-// Eyeballed value.
-const EdgeInsets _kToolbarButtonPadding = EdgeInsets.symmetric(vertical: 16.0, horizontal: 18.0);
+const CupertinoDynamicColor _kToolbarPressedColor = CupertinoDynamicColor.withBrightness(
+ color: Color(0x10000000),
+ darkColor: Color(0x10FFFFFF),
+);
+
+// Value measured from screenshot of iOS 16.0.2
+const EdgeInsets _kToolbarButtonPadding = EdgeInsets.symmetric(vertical: 18.0, horizontal: 16.0);
/// A button in the style of the iOS text selection toolbar buttons.
-class CupertinoTextSelectionToolbarButton extends StatelessWidget {
+class CupertinoTextSelectionToolbarButton extends StatefulWidget {
/// Create an instance of [CupertinoTextSelectionToolbarButton].
///
/// [child] cannot be null.
@@ -107,6 +105,7 @@
return localizations.pasteButtonLabel;
case ContextMenuButtonType.selectAll:
return localizations.selectAllButtonLabel;
+ case ContextMenuButtonType.liveTextInput:
case ContextMenuButtonType.delete:
case ContextMenuButtonType.custom:
return '';
@@ -114,25 +113,138 @@
}
@override
- Widget build(BuildContext context) {
- final Widget child = this.child ?? Text(
- text ?? getButtonLabel(context, buttonItem!),
- overflow: TextOverflow.ellipsis,
- style: _kToolbarButtonFontStyle.copyWith(
- color: onPressed != null
- ? _kToolbarTextColor.resolveFrom(context)
- : CupertinoColors.inactiveGray,
- ),
- );
+ State<StatefulWidget> createState() => _CupertinoTextSelectionToolbarButtonState();
+}
- return CupertinoButton(
+class _CupertinoTextSelectionToolbarButtonState extends State<CupertinoTextSelectionToolbarButton> {
+ bool isPressed = false;
+
+ void _onTapDown(TapDownDetails details) {
+ setState(() => isPressed = true);
+ }
+
+ void _onTapUp(TapUpDetails details) {
+ setState(() => isPressed = false);
+ widget.onPressed?.call();
+ }
+
+ void _onTapCancel() {
+ setState(() => isPressed = false);
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ final Widget content = _getContentWidget(context);
+ final Widget child = CupertinoButton(
+ color: isPressed
+ ? _kToolbarPressedColor.resolveFrom(context)
+ : const Color(0x00000000),
borderRadius: null,
- color: _kToolbarBackgroundColor,
- disabledColor: _kToolbarBackgroundColor,
- onPressed: onPressed,
+ disabledColor: const Color(0x00000000),
+ // This CupertinoButton does not actually handle the onPressed callback,
+ // this is only here to correctly enable/disable the button (see
+ // GestureDetector comment below).
+ onPressed: widget.onPressed,
padding: _kToolbarButtonPadding,
- pressedOpacity: onPressed == null ? 1.0 : 0.7,
- child: child,
+ // There's no foreground fade on iOS toolbar anymore, just the background
+ // is darkened.
+ pressedOpacity: 1.0,
+ child: content,
);
+
+ if (widget.onPressed != null) {
+ // As it's needed to change the CupertinoButton's backgroundColor when
+ // pressed, not its opacity, this GestureDetector handles both the
+ // onPressed callback and the backgroundColor change.
+ return GestureDetector(
+ onTapDown: _onTapDown,
+ onTapUp: _onTapUp,
+ onTapCancel: _onTapCancel,
+ child: child,
+ );
+ } else {
+ return child;
+ }
+ }
+
+ Widget _getContentWidget(BuildContext context) {
+ if (widget.child != null) {
+ return widget.child!;
+ }
+ final Widget textWidget = Text(
+ widget.text ?? CupertinoTextSelectionToolbarButton.getButtonLabel(context, widget.buttonItem!),
+ overflow: TextOverflow.ellipsis,
+ style: _kToolbarButtonFontStyle.copyWith(
+ color: widget.onPressed != null
+ ? _kToolbarTextColor.resolveFrom(context)
+ : CupertinoColors.inactiveGray,
+ ),
+ );
+ if (widget.buttonItem == null) {
+ return textWidget;
+ }
+ switch (widget.buttonItem!.type) {
+ case ContextMenuButtonType.cut:
+ case ContextMenuButtonType.copy:
+ case ContextMenuButtonType.paste:
+ case ContextMenuButtonType.selectAll:
+ case ContextMenuButtonType.delete:
+ case ContextMenuButtonType.custom:
+ return textWidget;
+ case ContextMenuButtonType.liveTextInput:
+ return SizedBox(
+ width: 13.0,
+ height: 13.0,
+ child: CustomPaint(
+ painter: _LiveTextIconPainter(color: _kToolbarTextColor.resolveFrom(context)),
+ ),
+ );
+ }
+ }
+}
+
+class _LiveTextIconPainter extends CustomPainter {
+ _LiveTextIconPainter({required this.color});
+
+ final Color color;
+
+ final Paint _painter = Paint()
+ ..strokeCap = StrokeCap.round
+ ..strokeJoin = StrokeJoin.round
+ ..strokeWidth = 1.0
+ ..style = PaintingStyle.stroke;
+
+ @override
+ void paint(Canvas canvas, Size size) {
+ _painter.color = color;
+ canvas.save();
+ canvas.translate(size.width / 2.0, size.height / 2.0);
+
+ final Offset origin = Offset(-size.width / 2.0, -size.height / 2.0);
+ // Path for the one corner.
+ final Path path = Path()
+ ..moveTo(origin.dx, origin.dy + 3.5)
+ ..lineTo(origin.dx, origin.dy + 1.0)
+ ..arcToPoint(Offset(origin.dx + 1.0, origin.dy), radius: const Radius.circular(1))
+ ..lineTo(origin.dx + 3.5, origin.dy);
+
+ // Rotate to draw corner four times.
+ final Matrix4 rotationMatrix = Matrix4.identity()..rotateZ(pi / 2.0);
+ for (int i = 0; i < 4; i += 1) {
+ canvas.drawPath(path, _painter);
+ canvas.transform(rotationMatrix.storage);
+ }
+
+ // Draw three lines.
+ canvas.drawLine(const Offset(-3.0, -3.0), const Offset(3.0, -3.0), _painter);
+ canvas.drawLine(const Offset(-3.0, 0.0), const Offset(3.0, 0.0), _painter);
+ canvas.drawLine(const Offset(-3.0, 3.0), const Offset(1.0, 3.0), _painter);
+
+ canvas.restore();
+ }
+
+ @override
+ bool shouldRepaint(covariant _LiveTextIconPainter oldDelegate) {
+ return oldDelegate.color != color;
}
}
diff --git a/packages/flutter/lib/src/foundation/_timeline_io.dart b/packages/flutter/lib/src/foundation/_timeline_io.dart
new file mode 100644
index 0000000..8c4886b
--- /dev/null
+++ b/packages/flutter/lib/src/foundation/_timeline_io.dart
@@ -0,0 +1,11 @@
+// Copyright 2014 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'dart:developer';
+
+/// Returns the current timestamp in microseconds from a monotonically
+/// increasing clock.
+///
+/// This is the Dart VM implementation.
+double get performanceTimestamp => Timeline.now.toDouble();
diff --git a/packages/flutter/lib/src/foundation/_timeline_web.dart b/packages/flutter/lib/src/foundation/_timeline_web.dart
new file mode 100644
index 0000000..133f096
--- /dev/null
+++ b/packages/flutter/lib/src/foundation/_timeline_web.dart
@@ -0,0 +1,27 @@
+// Copyright 2014 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'dart:js_interop';
+
+/// Returns the current timestamp in microseconds from a monotonically
+/// increasing clock.
+///
+/// This is the web implementation, which uses `window.performance.now` as the
+/// source of the timestamp.
+///
+/// See:
+/// * https://developer.mozilla.org/en-US/docs/Web/API/Performance/now
+double get performanceTimestamp => 1000 * _performance.now();
+
+@JS()
+@staticInterop
+class _DomPerformance {}
+
+@JS('performance')
+external _DomPerformance get _performance;
+
+extension _DomPerformanceExtension on _DomPerformance {
+ @JS()
+ external double now();
+}
diff --git a/packages/flutter/lib/src/foundation/binding.dart b/packages/flutter/lib/src/foundation/binding.dart
index 8532f6d..bc451ac 100644
--- a/packages/flutter/lib/src/foundation/binding.dart
+++ b/packages/flutter/lib/src/foundation/binding.dart
@@ -20,6 +20,7 @@
import 'platform.dart';
import 'print.dart';
import 'service_extensions.dart';
+import 'timeline.dart';
export 'dart:ui' show PlatformDispatcher, SingletonFlutterWindow; // ignore: deprecated_member_use
@@ -141,7 +142,9 @@
/// [initServiceExtensions] to have bindings initialize their
/// VM service extensions, if any.
BindingBase() {
- developer.Timeline.startSync('Framework initialization');
+ if (!kReleaseMode) {
+ FlutterTimeline.startSync('Framework initialization');
+ }
assert(() {
_debugConstructed = true;
return true;
@@ -157,7 +160,9 @@
developer.postEvent('Flutter.FrameworkInitialization', <String, String>{});
- developer.Timeline.finishSync();
+ if (!kReleaseMode) {
+ FlutterTimeline.finishSync();
+ }
}
bool _debugConstructed = false;
diff --git a/packages/flutter/lib/src/foundation/diagnostics.dart b/packages/flutter/lib/src/foundation/diagnostics.dart
index 280a881..f4f9d5c 100644
--- a/packages/flutter/lib/src/foundation/diagnostics.dart
+++ b/packages/flutter/lib/src/foundation/diagnostics.dart
@@ -3292,6 +3292,8 @@
/// {@end-tool}
///
/// Used by [toDiagnosticsNode] and [toString].
+ ///
+ /// Do not add values, that have lifetime shorter than the object.
@protected
@mustCallSuper
void debugFillProperties(DiagnosticPropertiesBuilder properties) { }
diff --git a/packages/flutter/lib/src/foundation/node.dart b/packages/flutter/lib/src/foundation/node.dart
index 6e830f1..ca383fb 100644
--- a/packages/flutter/lib/src/foundation/node.dart
+++ b/packages/flutter/lib/src/foundation/node.dart
@@ -8,6 +8,10 @@
// during device lab performance tests. When editing this file, check to make sure
// that it didn't break that test.
+/// Deprecated. Unused by the framework and will be removed in a future version
+/// of Flutter. If needed, inline any required functionality of this class
+/// directly in the subclass.
+///
/// An abstract node in a tree.
///
/// AbstractNode has as notion of depth, attachment, and parent, but does not
@@ -39,6 +43,10 @@
/// moved to be a child of A, sibling of B, then the numbers won't change. C's
/// [depth] will still be 2. The [depth] is automatically maintained by the
/// [adoptChild] and [dropChild] methods.
+@Deprecated(
+ 'If needed, inline any required functionality of AbstractNode in your class directly. '
+ 'This feature was deprecated after v3.12.0-4.0.pre.',
+)
class AbstractNode {
/// The depth of this node in the tree.
///
diff --git a/packages/flutter/lib/src/foundation/timeline.dart b/packages/flutter/lib/src/foundation/timeline.dart
new file mode 100644
index 0000000..b110ea0
--- /dev/null
+++ b/packages/flutter/lib/src/foundation/timeline.dart
@@ -0,0 +1,432 @@
+// Copyright 2014 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'dart:developer';
+import 'dart:typed_data';
+
+import 'package:meta/meta.dart';
+
+import '_timeline_io.dart'
+ if (dart.library.js_util) '_timeline_web.dart' as impl;
+import 'constants.dart';
+
+/// Measures how long blocks of code take to run.
+///
+/// This class can be used as a drop-in replacement for [Timeline] as it
+/// provides methods compatible with [Timeline] signature-wise, and it has
+/// minimal overhead.
+///
+/// Provides [debugReset] and [debugCollect] methods that make it convenient to use in
+/// frame-oriented environment where collected metrics can be attributed to a
+/// frame, then aggregated into frame statistics, e.g. frame averages.
+///
+/// Forwards measurements to [Timeline] so they appear in Flutter DevTools.
+abstract final class FlutterTimeline {
+ static _BlockBuffer _buffer = _BlockBuffer();
+
+ /// Whether block timings are collected and can be retrieved using the
+ /// [debugCollect] method.
+ ///
+ /// This is always false in release mode.
+ static bool get debugCollectionEnabled => _collectionEnabled;
+
+ /// Enables metric collection.
+ ///
+ /// Metric collection can only be enabled in non-release modes. It is most
+ /// useful in profile mode where application performance is representative
+ /// of a deployed application.
+ ///
+ /// When disabled, resets collected data by calling [debugReset].
+ ///
+ /// Throws a [StateError] if invoked in release mode.
+ static set debugCollectionEnabled(bool value) {
+ if (kReleaseMode) {
+ throw _createReleaseModeNotSupportedError();
+ }
+ if (value == _collectionEnabled) {
+ return;
+ }
+ _collectionEnabled = value;
+ debugReset();
+ }
+
+ static StateError _createReleaseModeNotSupportedError() {
+ return StateError('FlutterTimeline metric collection not supported in release mode.');
+ }
+
+ static bool _collectionEnabled = false;
+
+ /// Start a synchronous operation labeled `name`.
+ ///
+ /// Optionally takes a map of `arguments`. This slice may also optionally be
+ /// associated with a [Flow] event. This operation must be finished by calling
+ /// [finishSync] before returning to the event queue.
+ ///
+ /// This is a drop-in replacement for [Timeline.startSync].
+ static void startSync(String name, { Map<String, Object?>? arguments, Flow? flow }) {
+ Timeline.startSync(name, arguments: arguments, flow: flow);
+ if (!kReleaseMode && _collectionEnabled) {
+ _buffer.startSync(name, arguments: arguments, flow: flow);
+ }
+ }
+
+ /// Finish the last synchronous operation that was started.
+ ///
+ /// This is a drop-in replacement for [Timeline.finishSync].
+ static void finishSync() {
+ Timeline.finishSync();
+ if (!kReleaseMode && _collectionEnabled) {
+ _buffer.finishSync();
+ }
+ }
+
+ /// Emit an instant event.
+ ///
+ /// This is a drop-in replacement for [Timeline.instantSync].
+ static void instantSync(String name, { Map<String, Object?>? arguments }) {
+ Timeline.instantSync(name, arguments: arguments);
+ }
+
+ /// A utility method to time a synchronous `function`. Internally calls
+ /// `function` bracketed by calls to [startSync] and [finishSync].
+ ///
+ /// This is a drop-in replacement for [Timeline.timeSync].
+ static T timeSync<T>(String name, TimelineSyncFunction<T> function,
+ { Map<String, Object?>? arguments, Flow? flow }) {
+ startSync(name, arguments: arguments, flow: flow);
+ try {
+ return function();
+ } finally {
+ finishSync();
+ }
+ }
+
+ /// The current time stamp from the clock used by the timeline in
+ /// microseconds.
+ ///
+ /// When run on the Dart VM, uses the same monotonic clock as the embedding
+ /// API's `Dart_TimelineGetMicros`.
+ ///
+ /// When run on the web, uses `window.performance.now`.
+ ///
+ /// This is a drop-in replacement for [Timeline.now].
+ static int get now => impl.performanceTimestamp.toInt();
+
+ /// Returns timings collected since [debugCollectionEnabled] was set to true,
+ /// since the previous [debugCollect], or since the previous [debugReset],
+ /// whichever was last.
+ ///
+ /// Resets the collected timings.
+ ///
+ /// This is only meant to be used in non-release modes, typically in profile
+ /// mode that provides timings close to release mode timings.
+ static AggregatedTimings debugCollect() {
+ if (kReleaseMode) {
+ throw _createReleaseModeNotSupportedError();
+ }
+ if (!_collectionEnabled) {
+ throw StateError('Timeline metric collection not enabled.');
+ }
+ final AggregatedTimings result = AggregatedTimings(_buffer.computeTimings());
+ debugReset();
+ return result;
+ }
+
+ /// Forgets all previously collected timing data.
+ ///
+ /// Use this method to scope metrics to a frame, a pointer event, or any
+ /// other event. To do that, call [debugReset] at the start of the event, then
+ /// call [debugCollect] at the end of the event.
+ ///
+ /// This is only meant to be used in non-release modes.
+ static void debugReset() {
+ if (kReleaseMode) {
+ throw _createReleaseModeNotSupportedError();
+ }
+ _buffer = _BlockBuffer();
+ }
+}
+
+/// Provides [start], [end], and [duration] of a named block of code, timed by
+/// [FlutterTimeline].
+@immutable
+final class TimedBlock {
+ /// Creates a timed block of code from a [name], [start], and [end].
+ ///
+ /// The [name] should be sufficiently unique and descriptive for someone to
+ /// easily tell which part of code was measured.
+ const TimedBlock({
+ required this.name,
+ required this.start,
+ required this.end,
+ }) : assert(end >= start, 'The start timestamp must not be greater than the end timestamp.');
+
+ /// A readable label for a block of code that was measured.
+ ///
+ /// This field should be sufficiently unique and descriptive for someone to
+ /// easily tell which part of code was measured.
+ final String name;
+
+ /// The timestamp in microseconds that marks the beginning of the measured
+ /// block of code.
+ final double start;
+
+ /// The timestamp in microseconds that marks the end of the measured block of
+ /// code.
+ final double end;
+
+ /// How long the measured block of code took to execute in microseconds.
+ double get duration => end - start;
+
+ @override
+ String toString() {
+ return 'TimedBlock($name, $start, $end, $duration)';
+ }
+}
+
+/// Provides aggregated results for timings collected by [FlutterTimeline].
+@immutable
+final class AggregatedTimings {
+ /// Creates aggregated timings for the provided timed blocks.
+ AggregatedTimings(this.timedBlocks);
+
+ /// All timed blocks collected between the last reset and [FlutterTimeline.debugCollect].
+ final List<TimedBlock> timedBlocks;
+
+ /// Aggregated timed blocks collected between the last reset and [FlutterTimeline.debugCollect].
+ ///
+ /// Does not guarantee that all code blocks will be reported. Only those that
+ /// executed since the last reset are listed here. Use [getAggregated] for
+ /// graceful handling of missing code blocks.
+ late final List<AggregatedTimedBlock> aggregatedBlocks = _computeAggregatedBlocks();
+
+ List<AggregatedTimedBlock> _computeAggregatedBlocks() {
+ final Map<String, (double, int)> aggregate = <String, (double, int)>{};
+ for (final TimedBlock block in timedBlocks) {
+ final (double, int) previousValue = aggregate.putIfAbsent(block.name, () => (0, 0));
+ aggregate[block.name] = (previousValue.$1 + block.duration, previousValue.$2 + 1);
+ }
+ return aggregate.entries.map<AggregatedTimedBlock>(
+ (MapEntry<String, (double, int)> entry) {
+ return AggregatedTimedBlock(name: entry.key, duration: entry.value.$1, count: entry.value.$2);
+ }
+ ).toList();
+ }
+
+ /// Returns aggregated numbers for a named block of code.
+ ///
+ /// If the block in question never executed since the last reset, returns an
+ /// aggregation with zero duration and count.
+ AggregatedTimedBlock getAggregated(String name) {
+ return aggregatedBlocks.singleWhere(
+ (AggregatedTimedBlock block) => block.name == name,
+ // Handle the case where there are no recorded blocks of the specified
+ // type. In this case, the aggregated duration is simply zero, and so is
+ // the number of occurrences (i.e. count).
+ orElse: () => AggregatedTimedBlock(name: name, duration: 0, count: 0),
+ );
+ }
+}
+
+/// Aggregates multiple [TimedBlock] objects that share a [name].
+///
+/// It is common for the same block of code to be executed multiple times within
+/// a frame. It is useful to combine multiple executions and report the total
+/// amount of time attributed to that block of code.
+@immutable
+final class AggregatedTimedBlock {
+ /// Creates a timed block of code from a [name] and [duration].
+ ///
+ /// The [name] should be sufficiently unique and descriptive for someone to
+ /// easily tell which part of code was measured.
+ const AggregatedTimedBlock({
+ required this.name,
+ required this.duration,
+ required this.count,
+ }) : assert(duration >= 0);
+
+ /// A readable label for a block of code that was measured.
+ ///
+ /// This field should be sufficiently unique and descriptive for someone to
+ /// easily tell which part of code was measured.
+ final String name;
+
+ /// The sum of [TimedBlock.duration] values of aggretaged blocks.
+ final double duration;
+
+ /// The number of [TimedBlock] objects aggregated.
+ final int count;
+
+ @override
+ String toString() {
+ return 'AggregatedTimedBlock($name, $duration, $count)';
+ }
+}
+
+const int _kSliceSize = 500;
+
+/// A growable list of float64 values with predictable [add] performance.
+///
+/// The list is organized into a "chain" of [Float64List]s. The object starts
+/// with a `Float64List` "slice". When [add] is called, the value is added to
+/// the slice. Once the slice is full, it is moved into the chain, and a new
+/// slice is allocated. Slice size is static and therefore its allocation has
+/// predictable cost. This is unlike the default [List] implementation, which,
+/// when full, doubles its buffer size and copies all old elements into the new
+/// buffer, leading to unpredictable performance. This makes it a poor choice
+/// for recording performance because buffer reallocation would affect the
+/// runtime.
+///
+/// The trade-off is that reading values back from the chain is more expensive
+/// compared to [List] because it requires iterating over multiple slices. This
+/// is a reasonable trade-off for performance metrics, because it is more
+/// important to minimize the overhead while recording metrics, than it is when
+/// reading them.
+final class _Float64ListChain {
+ _Float64ListChain();
+
+ final List<Float64List> _chain = <Float64List>[];
+ Float64List _slice = Float64List(_kSliceSize);
+ int _pointer = 0;
+
+ int get length => _length;
+ int _length = 0;
+
+ /// Adds and [element] to this chain.
+ void add(double element) {
+ _slice[_pointer] = element;
+ _pointer += 1;
+ _length += 1;
+ if (_pointer >= _kSliceSize) {
+ _chain.add(_slice);
+ _slice = Float64List(_kSliceSize);
+ _pointer = 0;
+ }
+ }
+
+ /// Returns all elements added to this chain.
+ ///
+ /// This getter is not optimized to be fast. It is assumed that when metrics
+ /// are read back, they do not affect the timings of the work being
+ /// benchmarked.
+ List<double> extractElements() {
+ final List<double> result = <double>[];
+ _chain.forEach(result.addAll);
+ for (int i = 0; i < _pointer; i++) {
+ result.add(_slice[i]);
+ }
+ return result;
+ }
+}
+
+/// Same as [_Float64ListChain] but for recording string values.
+final class _StringListChain {
+ _StringListChain();
+
+ final List<List<String?>> _chain = <List<String?>>[];
+ List<String?> _slice = List<String?>.filled(_kSliceSize, null);
+ int _pointer = 0;
+
+ int get length => _length;
+ int _length = 0;
+
+ /// Adds and [element] to this chain.
+ void add(String element) {
+ _slice[_pointer] = element;
+ _pointer += 1;
+ _length += 1;
+ if (_pointer >= _kSliceSize) {
+ _chain.add(_slice);
+ _slice = List<String?>.filled(_kSliceSize, null);
+ _pointer = 0;
+ }
+ }
+
+ /// Returns all elements added to this chain.
+ ///
+ /// This getter is not optimized to be fast. It is assumed that when metrics
+ /// are read back, they do not affect the timings of the work being
+ /// benchmarked.
+ List<String> extractElements() {
+ final List<String> result = <String>[];
+ for (final List<String?> slice in _chain) {
+ for (final String? element in slice) {
+ result.add(element!);
+ }
+ }
+ for (int i = 0; i < _pointer; i++) {
+ result.add(_slice[i]!);
+ }
+ return result;
+ }
+}
+
+/// A buffer that records starts and ends of code blocks, and their names.
+final class _BlockBuffer {
+ // Start-finish blocks can be nested. Track this nestedness by stacking the
+ // start timestamps. Finish timestamps will pop timings from the stack and
+ // add the (start, finish) tuple to the _block.
+ static const int _stackDepth = 1000;
+ static final Float64List _startStack = Float64List(_stackDepth);
+ static final List<String?> _nameStack = List<String?>.filled(_stackDepth, null);
+ static int _stackPointer = 0;
+
+ final _Float64ListChain _starts = _Float64ListChain();
+ final _Float64ListChain _finishes = _Float64ListChain();
+ final _StringListChain _names = _StringListChain();
+
+ List<TimedBlock> computeTimings() {
+ assert(
+ _stackPointer == 0,
+ 'Invalid sequence of `startSync` and `finishSync`.\n'
+ 'The operation stack was not empty. The following operations are still '
+ 'waiting to be finished via the `finishSync` method:\n'
+ '${List<String>.generate(_stackPointer, (int i) => _nameStack[i]!).join(', ')}'
+ );
+
+ final List<TimedBlock> result = <TimedBlock>[];
+ final int length = _finishes.length;
+ final List<double> starts = _starts.extractElements();
+ final List<double> finishes = _finishes.extractElements();
+ final List<String> names = _names.extractElements();
+
+ assert(starts.length == length);
+ assert(finishes.length == length);
+ assert(names.length == length);
+
+ for (int i = 0; i < length; i++) {
+ result.add(TimedBlock(
+ start: starts[i],
+ end: finishes[i],
+ name: names[i],
+ ));
+ }
+
+ return result;
+ }
+
+ void startSync(String name, { Map<String, Object?>? arguments, Flow? flow }) {
+ _startStack[_stackPointer] = impl.performanceTimestamp;
+ _nameStack[_stackPointer] = name;
+ _stackPointer += 1;
+ }
+
+ void finishSync() {
+ assert(
+ _stackPointer > 0,
+ 'Invalid sequence of `startSync` and `finishSync`.\n'
+ 'Attempted to finish timing a block of code, but there are no pending '
+ '`startSync` calls.'
+ );
+
+ final double finishTime = impl.performanceTimestamp;
+ final double startTime = _startStack[_stackPointer - 1];
+ final String name = _nameStack[_stackPointer - 1]!;
+ _stackPointer -= 1;
+
+ _starts.add(startTime);
+ _finishes.add(finishTime);
+ _names.add(name);
+ }
+}
diff --git a/packages/flutter/lib/src/gestures/converter.dart b/packages/flutter/lib/src/gestures/converter.dart
index 5a5fcdd..21095d1 100644
--- a/packages/flutter/lib/src/gestures/converter.dart
+++ b/packages/flutter/lib/src/gestures/converter.dart
@@ -304,11 +304,6 @@
scale: datum.scale,
);
case ui.PointerSignalKind.unknown:
- default: // ignore: no_default_cases, to allow adding a new [PointerSignalKind] - PointerStylusAuxiliaryAction
- // TODO(louisehsu): remove after landing engine PR https://github.com/flutter/engine/pull/39637
- // This branch should already have 'unknown' filtered out, but
- // we don't want to return anything or miss if someone adds a new
- // enumeration to PointerSignalKind.
throw StateError('Unreachable');
}
}).whereType<PointerEvent>();
diff --git a/packages/flutter/lib/src/gestures/debug.dart b/packages/flutter/lib/src/gestures/debug.dart
index 59173dd..0bc9343 100644
--- a/packages/flutter/lib/src/gestures/debug.dart
+++ b/packages/flutter/lib/src/gestures/debug.dart
@@ -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 'package:flutter/foundation.dart';
// Any changes to this file should be reflected in the debugAssertAllGesturesVarsUnset()
diff --git a/packages/flutter/lib/src/gestures/long_press.dart b/packages/flutter/lib/src/gestures/long_press.dart
index 91a11c7..1c759c2 100644
--- a/packages/flutter/lib/src/gestures/long_press.dart
+++ b/packages/flutter/lib/src/gestures/long_press.dart
@@ -645,7 +645,7 @@
_initialButtons = event.buttons;
_checkLongPressDown(event);
} else if (event is PointerMoveEvent) {
- if (event.buttons != _initialButtons) {
+ if (event.buttons != _initialButtons && !_longPressAccepted) {
resolve(GestureDisposition.rejected);
stopTrackingPointer(primaryPointer!);
} else if (_longPressAccepted) {
diff --git a/packages/flutter/lib/src/material/action_chip.dart b/packages/flutter/lib/src/material/action_chip.dart
index 826842d..725570f 100644
--- a/packages/flutter/lib/src/material/action_chip.dart
+++ b/packages/flutter/lib/src/material/action_chip.dart
@@ -10,6 +10,7 @@
import 'color_scheme.dart';
import 'colors.dart';
import 'debug.dart';
+import 'material_state.dart';
import 'text_theme.dart';
import 'theme.dart';
import 'theme_data.dart';
@@ -49,6 +50,22 @@
/// Material Design 3. If [ThemeData.useMaterial3] is true, then [ActionChip]
/// will be styled to match the Material Design 3 Assist and Suggestion chips.
///
+/// ### Creating an Assist chip
+///
+/// Assist chips are used to provide a quick way to perform an action.
+/// To create an Action chip, set the icon property to the icon
+/// that represents the action and set the label to the name of the action.
+///
+///
+/// ### Creating a Suggestion chip
+///
+/// Suggestion chips usually display generated suggestions for the user,
+/// like a suggested response to a message.
+///
+/// To create a Suggestion chip, set the label to the suggestion
+/// and don't set the icon property.
+//
+///
/// See also:
///
/// * [Chip], a chip that displays information and can be deleted.
@@ -81,6 +98,7 @@
this.clipBehavior = Clip.none,
this.focusNode,
this.autofocus = false,
+ this.color,
this.backgroundColor,
this.disabledColor,
this.padding,
@@ -113,6 +131,7 @@
this.clipBehavior = Clip.none,
this.focusNode,
this.autofocus = false,
+ this.color,
this.backgroundColor,
this.disabledColor,
this.padding,
@@ -151,6 +170,8 @@
@override
final bool autofocus;
@override
+ final MaterialStateProperty<Color?>? color;
+ @override
final Color? backgroundColor;
@override
final Color? disabledColor;
@@ -188,6 +209,7 @@
pressElevation: pressElevation,
tooltip: tooltip,
labelStyle: labelStyle,
+ color: color,
backgroundColor: backgroundColor,
side: side,
shape: shape,
@@ -239,7 +261,15 @@
TextStyle? get labelStyle => _textTheme.labelLarge;
@override
- Color? get backgroundColor => null;
+ MaterialStateProperty<Color?>? get color =>
+ MaterialStateProperty.resolveWith((Set<MaterialState> states) {
+ if (states.contains(MaterialState.disabled)) {
+ return _chipVariant == _ChipVariant.flat
+ ? null
+ : _colors.onSurface.withOpacity(0.12);
+ }
+ return null;
+ });
@override
Color? get shadowColor => _chipVariant == _ChipVariant.flat
@@ -250,17 +280,9 @@
Color? get surfaceTintColor => _colors.surfaceTint;
@override
- Color? get selectedColor => null;
-
- @override
Color? get checkmarkColor => null;
@override
- Color? get disabledColor => _chipVariant == _ChipVariant.flat
- ? null
- : _colors.onSurface.withOpacity(0.12);
-
- @override
Color? get deleteIconColor => null;
@override
diff --git a/packages/flutter/lib/src/material/action_icons_theme.dart b/packages/flutter/lib/src/material/action_icons_theme.dart
index 7dd6987..6c291e6 100644
--- a/packages/flutter/lib/src/material/action_icons_theme.dart
+++ b/packages/flutter/lib/src/material/action_icons_theme.dart
@@ -114,6 +114,13 @@
/// An inherited widget that overrides the default icon of [BackButtonIcon],
/// [CloseButtonIcon], [DrawerButtonIcon], and [EndDrawerButtonIcon] in this
/// widget's subtree.
+///
+/// {@tool dartpad}
+/// This example shows how to define custom builders for drawer and back
+/// buttons.
+///
+/// ** See code in examples/api/lib/material/action_buttons/action_icon_theme.0.dart **
+/// {@end-tool}
class ActionIconTheme extends InheritedTheme {
/// Creates a theme that overrides the default icon of [BackButtonIcon],
/// [CloseButtonIcon], [DrawerButtonIcon], and [EndDrawerButtonIcon] in this
diff --git a/packages/flutter/lib/src/material/adaptive_text_selection_toolbar.dart b/packages/flutter/lib/src/material/adaptive_text_selection_toolbar.dart
index e39e709..0d32cfe 100644
--- a/packages/flutter/lib/src/material/adaptive_text_selection_toolbar.dart
+++ b/packages/flutter/lib/src/material/adaptive_text_selection_toolbar.dart
@@ -103,6 +103,7 @@
required VoidCallback? onCut,
required VoidCallback? onPaste,
required VoidCallback? onSelectAll,
+ required VoidCallback? onLiveTextInput,
required this.anchors,
}) : children = null,
buttonItems = EditableText.getEditableButtonItems(
@@ -111,6 +112,7 @@
onCut: onCut,
onPaste: onPaste,
onSelectAll: onSelectAll,
+ onLiveTextInput: onLiveTextInput
);
/// Create an instance of [AdaptiveTextSelectionToolbar] with the default
@@ -213,6 +215,8 @@
return localizations.selectAllButtonLabel;
case ContextMenuButtonType.delete:
return localizations.deleteButtonTooltip.toUpperCase();
+ case ContextMenuButtonType.liveTextInput:
+ return localizations.scanTextButtonLabel;
case ContextMenuButtonType.custom:
return '';
}
@@ -242,9 +246,8 @@
switch (Theme.of(context).platform) {
case TargetPlatform.iOS:
return buttonItems.map((ContextMenuButtonItem buttonItem) {
- return CupertinoTextSelectionToolbarButton.text(
- onPressed: buttonItem.onPressed,
- text: getButtonLabel(context, buttonItem),
+ return CupertinoTextSelectionToolbarButton.buttonItem(
+ buttonItem: buttonItem,
);
});
case TargetPlatform.fuchsia:
diff --git a/packages/flutter/lib/src/material/autocomplete.dart b/packages/flutter/lib/src/material/autocomplete.dart
index 9f00633..c078018 100644
--- a/packages/flutter/lib/src/material/autocomplete.dart
+++ b/packages/flutter/lib/src/material/autocomplete.dart
@@ -66,6 +66,7 @@
this.onSelected,
this.optionsMaxHeight = 200.0,
this.optionsViewBuilder,
+ this.optionsViewOpenDirection = OptionsViewOpenDirection.down,
this.initialValue,
});
@@ -90,6 +91,9 @@
/// default.
final AutocompleteOptionsViewBuilder<T>? optionsViewBuilder;
+ /// {@macro flutter.widgets.RawAutocomplete.optionsViewOpenDirection}
+ final OptionsViewOpenDirection optionsViewOpenDirection;
+
/// The maximum height used for the default Material options list widget.
///
/// When [optionsViewBuilder] is `null`, this property sets the maximum height
@@ -116,6 +120,7 @@
fieldViewBuilder: fieldViewBuilder,
initialValue: initialValue,
optionsBuilder: optionsBuilder,
+ optionsViewOpenDirection: optionsViewOpenDirection,
optionsViewBuilder: optionsViewBuilder ?? (BuildContext context, AutocompleteOnSelected<T> onSelected, Iterable<T> options) {
return _AutocompleteOptions<T>(
displayStringForOption: displayStringForOption,
diff --git a/packages/flutter/lib/src/material/calendar_date_picker.dart b/packages/flutter/lib/src/material/calendar_date_picker.dart
index 0032290..641ad3b 100644
--- a/packages/flutter/lib/src/material/calendar_date_picker.dart
+++ b/packages/flutter/lib/src/material/calendar_date_picker.dart
@@ -1013,6 +1013,8 @@
// for the day of month. To do that we prepend day of month to the
// formatted full date.
label: '${localizations.formatDecimal(day)}, ${localizations.formatFullDate(dayToBuild)}$semanticLabelSuffix',
+ // Set button to true to make the date selectable.
+ button: true,
selected: isSelectedDay,
excludeSemantics: true,
child: dayWidget,
diff --git a/packages/flutter/lib/src/material/chip.dart b/packages/flutter/lib/src/material/chip.dart
index d891c9a..eb45714 100644
--- a/packages/flutter/lib/src/material/chip.dart
+++ b/packages/flutter/lib/src/material/chip.dart
@@ -137,6 +137,13 @@
/// {@macro flutter.widgets.Focus.autofocus}
bool get autofocus;
+ /// The color that fills the chip, in all [MaterialState]s.
+ ///
+ /// Resolves in the following states:
+ /// * [MaterialState.selected].
+ /// * [MaterialState.disabled].
+ MaterialStateProperty<Color?>? get color;
+
/// Color to be used for the unselected, enabled chip's background.
///
/// The default is light grey.
@@ -561,6 +568,7 @@
this.clipBehavior = Clip.none,
this.focusNode,
this.autofocus = false,
+ this.color,
this.backgroundColor,
this.padding,
this.visualDensity,
@@ -595,6 +603,8 @@
@override
final bool autofocus;
@override
+ final MaterialStateProperty<Color?>? color;
+ @override
final Color? backgroundColor;
@override
final EdgeInsetsGeometry? padding;
@@ -644,6 +654,7 @@
clipBehavior: clipBehavior,
focusNode: focusNode,
autofocus: autofocus,
+ color: color,
backgroundColor: backgroundColor,
padding: padding,
visualDensity: visualDensity,
@@ -729,6 +740,7 @@
this.clipBehavior = Clip.none,
this.focusNode,
this.autofocus = false,
+ this.color,
this.backgroundColor,
this.materialTapTargetSize,
this.elevation,
@@ -798,6 +810,8 @@
@override
final bool autofocus;
@override
+ final MaterialStateProperty<Color?>? color;
+ @override
final Color? backgroundColor;
@override
final EdgeInsetsGeometry? padding;
@@ -987,23 +1001,47 @@
return resolvedShape.copyWith(side: resolvedSide);
}
+ Color? resolveColor({
+ MaterialStateProperty<Color?>? color,
+ Color? selectedColor,
+ Color? backgroundColor,
+ Color? disabledColor,
+ MaterialStateProperty<Color?>? defaultColor,
+ }) {
+ return _IndividualOverrides(
+ color: color,
+ selectedColor: selectedColor,
+ backgroundColor: backgroundColor,
+ disabledColor: disabledColor,
+ ).resolve(materialStates) ?? defaultColor?.resolve(materialStates);
+ }
+
/// Picks between three different colors, depending upon the state of two
/// different animations.
Color? _getBackgroundColor(ThemeData theme, ChipThemeData chipTheme, ChipThemeData chipDefaults) {
if (theme.useMaterial3) {
+ final Color? disabledColor = resolveColor(
+ color: widget.color ?? chipTheme.color,
+ disabledColor: widget.disabledColor ?? chipTheme.disabledColor,
+ defaultColor: chipDefaults.color,
+ );
+ final Color? backgroundColor = resolveColor(
+ color: widget.color ?? chipTheme.color,
+ backgroundColor: widget.backgroundColor ?? chipTheme.backgroundColor,
+ defaultColor: chipDefaults.color,
+ );
+ final Color? selectedColor = resolveColor(
+ color: widget.color ?? chipTheme.color,
+ selectedColor: widget.selectedColor ?? chipTheme.selectedColor,
+ defaultColor: chipDefaults.color,
+ );
final ColorTween backgroundTween = ColorTween(
- begin: widget.disabledColor
- ?? chipTheme.disabledColor
- ?? chipDefaults.disabledColor,
- end: widget.backgroundColor
- ?? chipTheme.backgroundColor
- ?? chipDefaults.backgroundColor,
+ begin: disabledColor,
+ end: backgroundColor,
);
final ColorTween selectTween = ColorTween(
begin: backgroundTween.evaluate(enableController),
- end: widget.selectedColor
- ?? chipTheme.selectedColor
- ?? chipDefaults.selectedColor,
+ end: selectedColor,
);
return selectTween.evaluate(selectionFade);
} else {
@@ -1295,6 +1333,37 @@
}
}
+class _IndividualOverrides extends MaterialStateProperty<Color?> {
+ _IndividualOverrides({
+ this.color,
+ this.backgroundColor,
+ this.selectedColor,
+ this.disabledColor,
+ });
+
+ final MaterialStateProperty<Color?>? color;
+ final Color? backgroundColor;
+ final Color? selectedColor;
+ final Color? disabledColor;
+
+ @override
+ Color? resolve(Set<MaterialState> states) {
+ if (color != null) {
+ return color!.resolve(states);
+ }
+ if (states.contains(MaterialState.selected) && states.contains(MaterialState.disabled)) {
+ return selectedColor;
+ }
+ if (states.contains(MaterialState.disabled)) {
+ return disabledColor;
+ }
+ if (states.contains(MaterialState.selected)) {
+ return selectedColor;
+ }
+ return backgroundColor;
+ }
+}
+
/// Redirects the [buttonRect.dy] passed to [RenderBox.hitTest] to the vertical
/// center of the widget.
///
@@ -2176,7 +2245,7 @@
TextStyle? get labelStyle => _textTheme.labelLarge;
@override
- Color? get backgroundColor => null;
+ MaterialStateProperty<Color?>? get color => null; // Subclasses override this getter
@override
Color? get shadowColor => Colors.transparent;
@@ -2185,15 +2254,9 @@
Color? get surfaceTintColor => _colors.surfaceTint;
@override
- Color? get selectedColor => null;
-
- @override
Color? get checkmarkColor => null;
@override
- Color? get disabledColor => null;
-
- @override
Color? get deleteIconColor => null;
@override
diff --git a/packages/flutter/lib/src/material/chip_theme.dart b/packages/flutter/lib/src/material/chip_theme.dart
index 32213d5..4c9a052 100644
--- a/packages/flutter/lib/src/material/chip_theme.dart
+++ b/packages/flutter/lib/src/material/chip_theme.dart
@@ -9,6 +9,7 @@
import 'package:flutter/widgets.dart';
import 'colors.dart';
+import 'material_state.dart';
import 'theme.dart';
/// Applies a chip theme to descendant [RawChip]-based widgets, like [Chip],
@@ -178,6 +179,7 @@
/// This will rarely be used directly. It is used by [lerp] to
/// create intermediate themes based on two themes.
const ChipThemeData({
+ this.color,
this.backgroundColor,
this.deleteIconColor,
this.disabledColor,
@@ -268,6 +270,12 @@
);
}
+ /// Overrides the default for [ChipAttributes.color].
+ ///
+ /// This property applies to [ActionChip], [Chip], [ChoiceChip],
+ /// [FilterChip], [InputChip], [RawChip].
+ final MaterialStateProperty<Color?>? color;
+
/// Overrides the default for [ChipAttributes.backgroundColor]
/// which is used for unselected, enabled chip backgrounds.
///
@@ -433,6 +441,7 @@
/// Creates a copy of this object but with the given fields replaced with the
/// new values.
ChipThemeData copyWith({
+ MaterialStateProperty<Color?>? color,
Color? backgroundColor,
Color? deleteIconColor,
Color? disabledColor,
@@ -455,6 +464,7 @@
IconThemeData? iconTheme,
}) {
return ChipThemeData(
+ color: color ?? this.color,
backgroundColor: backgroundColor ?? this.backgroundColor,
deleteIconColor: deleteIconColor ?? this.deleteIconColor,
disabledColor: disabledColor ?? this.disabledColor,
@@ -488,6 +498,7 @@
return a;
}
return ChipThemeData(
+ color: MaterialStateProperty.lerp<Color?>(a?.color, b?.color, t, Color.lerp),
backgroundColor: Color.lerp(a?.backgroundColor, b?.backgroundColor, t),
deleteIconColor: Color.lerp(a?.deleteIconColor, b?.deleteIconColor, t),
disabledColor: Color.lerp(a?.disabledColor, b?.disabledColor, t),
@@ -537,6 +548,7 @@
@override
int get hashCode => Object.hashAll(<Object?>[
+ color,
backgroundColor,
deleteIconColor,
disabledColor,
@@ -568,6 +580,7 @@
return false;
}
return other is ChipThemeData
+ && other.color == color
&& other.backgroundColor == backgroundColor
&& other.deleteIconColor == deleteIconColor
&& other.disabledColor == disabledColor
@@ -593,6 +606,7 @@
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
+ properties.add(DiagnosticsProperty<MaterialStateProperty<Color?>>('color', color, defaultValue: null));
properties.add(ColorProperty('backgroundColor', backgroundColor, defaultValue: null));
properties.add(ColorProperty('deleteIconColor', deleteIconColor, defaultValue: null));
properties.add(ColorProperty('disabledColor', disabledColor, defaultValue: null));
diff --git a/packages/flutter/lib/src/material/choice_chip.dart b/packages/flutter/lib/src/material/choice_chip.dart
index 50f4357..7b05db3 100644
--- a/packages/flutter/lib/src/material/choice_chip.dart
+++ b/packages/flutter/lib/src/material/choice_chip.dart
@@ -10,6 +10,7 @@
import 'color_scheme.dart';
import 'colors.dart';
import 'debug.dart';
+import 'material_state.dart';
import 'text_theme.dart';
import 'theme.dart';
import 'theme_data.dart';
@@ -78,6 +79,7 @@
this.clipBehavior = Clip.none,
this.focusNode,
this.autofocus = false,
+ this.color,
this.backgroundColor,
this.padding,
this.visualDensity,
@@ -116,6 +118,7 @@
this.clipBehavior = Clip.none,
this.focusNode,
this.autofocus = false,
+ this.color,
this.backgroundColor,
this.padding,
this.visualDensity,
@@ -163,6 +166,8 @@
@override
final bool autofocus;
@override
+ final MaterialStateProperty<Color?>? color;
+ @override
final Color? backgroundColor;
@override
final EdgeInsetsGeometry? padding;
@@ -218,6 +223,7 @@
autofocus: autofocus,
disabledColor: disabledColor,
selectedColor: selectedColor ?? chipTheme.secondarySelectedColor,
+ color: color,
backgroundColor: backgroundColor,
padding: padding,
visualDensity: visualDensity,
@@ -270,7 +276,27 @@
TextStyle? get labelStyle => _textTheme.labelLarge;
@override
- Color? get backgroundColor => null;
+ MaterialStateProperty<Color?>? get color =>
+ MaterialStateProperty.resolveWith((Set<MaterialState> states) {
+ if (states.contains(MaterialState.selected) && states.contains(MaterialState.disabled)) {
+ return _chipVariant == _ChipVariant.flat
+ ? _colors.onSurface.withOpacity(0.12)
+ : _colors.onSurface.withOpacity(0.12);
+ }
+ if (states.contains(MaterialState.disabled)) {
+ return _chipVariant == _ChipVariant.flat
+ ? null
+ : _colors.onSurface.withOpacity(0.12);
+ }
+ if (states.contains(MaterialState.selected)) {
+ return _chipVariant == _ChipVariant.flat
+ ? _colors.secondaryContainer
+ : _colors.secondaryContainer;
+ }
+ return _chipVariant == _ChipVariant.flat
+ ? null
+ : null;
+ });
@override
Color? get shadowColor => _chipVariant == _ChipVariant.flat
@@ -281,25 +307,9 @@
Color? get surfaceTintColor => _colors.surfaceTint;
@override
- Color? get selectedColor => _chipVariant == _ChipVariant.flat
- ? isEnabled
- ? _colors.secondaryContainer
- : _colors.onSurface.withOpacity(0.12)
- : isEnabled
- ? _colors.secondaryContainer
- : _colors.onSurface.withOpacity(0.12);
-
- @override
Color? get checkmarkColor => _colors.onSecondaryContainer;
@override
- Color? get disabledColor => _chipVariant == _ChipVariant.flat
- ? isSelected
- ? _colors.onSurface.withOpacity(0.12)
- : null
- : _colors.onSurface.withOpacity(0.12);
-
- @override
Color? get deleteIconColor => _colors.onSecondaryContainer;
@override
diff --git a/packages/flutter/lib/src/material/color_scheme.dart b/packages/flutter/lib/src/material/color_scheme.dart
index 44a52e1..3296678 100644
--- a/packages/flutter/lib/src/material/color_scheme.dart
+++ b/packages/flutter/lib/src/material/color_scheme.dart
@@ -898,29 +898,37 @@
/// Generate a [ColorScheme] derived from the given `imageProvider`.
///
/// Material Color Utilities extracts the dominant color from the
- /// supplied [ImageProvider]. Using this color, a set of tonal palettes are
- /// constructed. These tonal palettes are based on the Material 3 Color
- /// system and provide all the needed colors for a [ColorScheme]. These
- /// colors are designed to work well together and meet contrast
- /// requirements for accessibility.
+ /// supplied [ImageProvider]. Using this color, a [ColorScheme] is generated
+ /// with harmnonious colors that meet contrast requirements for accessibility.
///
/// If any of the optional color parameters are non-null, they will be
/// used in place of the generated colors for that field in the resulting
- /// color scheme. This allows apps to override specific colors for their
+ /// [ColorScheme]. This allows apps to override specific colors for their
/// needs.
///
/// Given the nature of the algorithm, the most dominant color of the
- /// `imageProvider` may not wind up as one of the ColorScheme colors.
+ /// `imageProvider` may not wind up as one of the [ColorScheme] colors.
///
/// The provided image will be scaled down to a maximum size of 112x112 pixels
/// during color extraction.
///
+ /// {@tool dartpad}
+ /// This sample shows how to use [ColorScheme.fromImageProvider] to create
+ /// content-based dynamic color schemes.
+ ///
+ /// ** See code in examples/api/lib/material/color_scheme/dynamic_content_color.0.dart **
+ /// {@end-tool}
+ ///
/// See also:
///
+ /// * [M3 Guidelines: Dynamic color from content](https://m3.material.io/styles/color/dynamic-color/user-generated-color#8af550b9-a19e-4e9f-bb0a-7f611fed5d0f)
+ /// * <https://pub.dev/packages/dynamic_color>, a package to create
+ /// [ColorScheme]s based on a platform's implementation of dynamic color.
/// * <https://m3.material.io/styles/color/the-color-system/color-roles>, the
/// Material 3 Color system specification.
/// * <https://pub.dev/packages/material_color_utilities>, the package
- /// used to generate the base color and tonal palettes needed for the scheme.
+ /// used to algorightmically determine the dominant color and to generate
+ /// the [ColorScheme].
static Future<ColorScheme> fromImageProvider({
required ImageProvider provider,
Brightness brightness = Brightness.light,
diff --git a/packages/flutter/lib/src/material/constants.dart b/packages/flutter/lib/src/material/constants.dart
index 4696cce..87064a5 100644
--- a/packages/flutter/lib/src/material/constants.dart
+++ b/packages/flutter/lib/src/material/constants.dart
@@ -51,11 +51,11 @@
const EdgeInsets kMaterialListPadding = EdgeInsets.symmetric(vertical: 8.0);
/// The default color for [ThemeData.iconTheme] when [ThemeData.brightness] is
-/// [Brightness.light]. This color is used in [IconButton] to detect whether
+/// [Brightness.dark]. This color is used in [IconButton] to detect whether
/// [IconTheme.of(context).color] is the same as the default color of [ThemeData.iconTheme].
const Color kDefaultIconLightColor = Colors.white;
/// The default color for [ThemeData.iconTheme] when [ThemeData.brightness] is
-/// [Brightness.dark]. This color is used in [IconButton] to detect whether
+/// [Brightness.light]. This color is used in [IconButton] to detect whether
/// [IconTheme.of(context).color] is the same as the default color of [ThemeData.iconTheme].
const Color kDefaultIconDarkColor = Colors.black87;
diff --git a/packages/flutter/lib/src/material/data_table.dart b/packages/flutter/lib/src/material/data_table.dart
index 970292c..b1c01ce 100644
--- a/packages/flutter/lib/src/material/data_table.dart
+++ b/packages/flutter/lib/src/material/data_table.dart
@@ -4,7 +4,6 @@
import 'dart:math' as math;
-import 'package:flutter/foundation.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
@@ -1202,7 +1201,7 @@
RectCallback getRectCallback(RenderBox referenceBox) {
return () {
RenderObject cell = referenceBox;
- AbstractNode? table = cell.parent;
+ RenderObject? table = cell.parent;
final Matrix4 transform = Matrix4.identity();
while (table is RenderObject && table is! RenderTable) {
table.applyPaintTransform(cell, transform);
diff --git a/packages/flutter/lib/src/material/date.dart b/packages/flutter/lib/src/material/date.dart
index 8d59527..b6e0082 100644
--- a/packages/flutter/lib/src/material/date.dart
+++ b/packages/flutter/lib/src/material/date.dart
@@ -67,7 +67,7 @@
///
/// `date` would be January 15, 2019.
/// `futureDate` would be April 1, 2019 since it adds 3 months.
- static DateTime addMonthsToMonthDate(DateTime monthDate, int monthsToAdd) {
+ static DateTime addMonthsToMonthDate(DateTime monthDate, int monthsToAdd) {
return DateTime(monthDate.year, monthDate.month + monthsToAdd);
}
diff --git a/packages/flutter/lib/src/material/date_picker_theme.dart b/packages/flutter/lib/src/material/date_picker_theme.dart
index 79cce12..a970ffb 100644
--- a/packages/flutter/lib/src/material/date_picker_theme.dart
+++ b/packages/flutter/lib/src/material/date_picker_theme.dart
@@ -9,6 +9,7 @@
import 'color_scheme.dart';
import 'colors.dart';
+import 'input_decorator.dart';
import 'material_state.dart';
import 'text_theme.dart';
import 'theme.dart';
@@ -68,6 +69,7 @@
this.rangeSelectionBackgroundColor,
this.rangeSelectionOverlayColor,
this.dividerColor,
+ this.inputDecorationTheme,
});
/// Overrides the default value of [Dialog.backgroundColor].
@@ -288,6 +290,10 @@
/// and vertical divider when the dialog is in landscape orientation.
final Color? dividerColor;
+ /// Overrides the [InputDatePickerFormField]'s input decoration theme.
+ /// If this is null, [ThemeData.inputDecorationTheme] is used instead.
+ final InputDecorationTheme? inputDecorationTheme;
+
/// Creates a copy of this object with the given fields replaced with the
/// new values.
DatePickerThemeData copyWith({
@@ -324,6 +330,7 @@
Color? rangeSelectionBackgroundColor,
MaterialStateProperty<Color?>? rangeSelectionOverlayColor,
Color? dividerColor,
+ InputDecorationTheme? inputDecorationTheme,
}) {
return DatePickerThemeData(
backgroundColor: backgroundColor ?? this.backgroundColor,
@@ -359,6 +366,7 @@
rangeSelectionBackgroundColor: rangeSelectionBackgroundColor ?? this.rangeSelectionBackgroundColor,
rangeSelectionOverlayColor: rangeSelectionOverlayColor ?? this.rangeSelectionOverlayColor,
dividerColor: dividerColor ?? this.dividerColor,
+ inputDecorationTheme: inputDecorationTheme ?? this.inputDecorationTheme,
);
}
@@ -401,6 +409,7 @@
rangeSelectionBackgroundColor: Color.lerp(a?.rangeSelectionBackgroundColor, b?.rangeSelectionBackgroundColor, t),
rangeSelectionOverlayColor: MaterialStateProperty.lerp<Color?>(a?.rangeSelectionOverlayColor, b?.rangeSelectionOverlayColor, t, Color.lerp),
dividerColor: Color.lerp(a?.dividerColor, b?.dividerColor, t),
+ inputDecorationTheme: t < 0.5 ? a?.inputDecorationTheme : b?.inputDecorationTheme,
);
}
@@ -449,6 +458,7 @@
rangeSelectionBackgroundColor,
rangeSelectionOverlayColor,
dividerColor,
+ inputDecorationTheme,
]);
@override
@@ -489,7 +499,8 @@
&& other.rangePickerHeaderHelpStyle == rangePickerHeaderHelpStyle
&& other.rangeSelectionBackgroundColor == rangeSelectionBackgroundColor
&& other.rangeSelectionOverlayColor == rangeSelectionOverlayColor
- && other.dividerColor == dividerColor;
+ && other.dividerColor == dividerColor
+ && other.inputDecorationTheme == inputDecorationTheme;
}
@override
@@ -528,6 +539,7 @@
properties.add(ColorProperty('rangeSelectionBackgroundColor', rangeSelectionBackgroundColor, defaultValue: null));
properties.add(DiagnosticsProperty<MaterialStateProperty<Color?>>('rangeSelectionOverlayColor', rangeSelectionOverlayColor, defaultValue: null));
properties.add(ColorProperty('dividerColor', dividerColor, defaultValue: null));
+ properties.add(DiagnosticsProperty<InputDecorationTheme>('inputDecorationTheme', inputDecorationTheme, defaultValue: null));
}
}
diff --git a/packages/flutter/lib/src/material/dropdown.dart b/packages/flutter/lib/src/material/dropdown.dart
index e948a87..a115b09 100644
--- a/packages/flutter/lib/src/material/dropdown.dart
+++ b/packages/flutter/lib/src/material/dropdown.dart
@@ -1221,7 +1221,6 @@
Orientation? _lastOrientation;
FocusNode? _internalNode;
FocusNode? get focusNode => widget.focusNode ?? _internalNode;
- bool _hasPrimaryFocus = false;
late Map<Type, Action<Intent>> _actionMap;
// Only used if needed to create _internalNode.
@@ -1244,14 +1243,12 @@
onInvoke: (ButtonActivateIntent intent) => _handleTap(),
),
};
- focusNode!.addListener(_handleFocusChanged);
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
_removeDropdownRoute();
- focusNode!.removeListener(_handleFocusChanged);
_internalNode?.dispose();
super.dispose();
}
@@ -1262,25 +1259,11 @@
_lastOrientation = null;
}
- void _handleFocusChanged() {
- if (_hasPrimaryFocus != focusNode!.hasPrimaryFocus) {
- setState(() {
- _hasPrimaryFocus = focusNode!.hasPrimaryFocus;
- });
- }
- }
-
-
@override
void didUpdateWidget(DropdownButton<T> oldWidget) {
super.didUpdateWidget(oldWidget);
- if (widget.focusNode != oldWidget.focusNode) {
- oldWidget.focusNode?.removeListener(_handleFocusChanged);
- if (widget.focusNode == null) {
- _internalNode ??= _createFocusNode();
- }
- _hasPrimaryFocus = focusNode!.hasPrimaryFocus;
- focusNode!.addListener(_handleFocusChanged);
+ if (widget.focusNode == null) {
+ _internalNode ??= _createFocusNode();
}
_updateSelectedIndex();
}
diff --git a/packages/flutter/lib/src/material/dropdown_menu.dart b/packages/flutter/lib/src/material/dropdown_menu.dart
index 802fdfe..4bf3cee 100644
--- a/packages/flutter/lib/src/material/dropdown_menu.dart
+++ b/packages/flutter/lib/src/material/dropdown_menu.dart
@@ -139,6 +139,7 @@
this.initialSelection,
this.onSelected,
this.requestFocusOnTap,
+ this.expandedInsets,
required this.dropdownMenuEntries,
});
@@ -277,6 +278,21 @@
/// contain space for padding.
final List<DropdownMenuEntry<T>> dropdownMenuEntries;
+ /// Defines the menu text field's width to be equal to its parent's width
+ /// plus the horizontal width of the specified insets.
+ ///
+ /// If this property is null, the width of the text field will be determined
+ /// by the width of menu items or [DropdownMenu.width]. If this property is not null,
+ /// the text field's width will match the parent's width plus the specified insets.
+ /// If the value of this property is [EdgeInsets.zero], the width of the text field will be the same
+ /// as its parent's width.
+ ///
+ /// The [expandedInsets]' top and bottom are ignored, only its left and right
+ /// properties are used.
+ ///
+ /// Defaults to null.
+ final EdgeInsets? expandedInsets;
+
@override
State<DropdownMenu<T>> createState() => _DropdownMenuState<T>();
}
@@ -284,6 +300,7 @@
class _DropdownMenuState<T> extends State<DropdownMenu<T>> {
final GlobalKey _anchorKey = GlobalKey();
final GlobalKey _leadingKey = GlobalKey();
+ late List<GlobalKey> buttonItemKeys;
final MenuController _controller = MenuController();
late final TextEditingController _textEditingController;
late bool _enableFilter;
@@ -299,6 +316,7 @@
_textEditingController = widget.controller ?? TextEditingController();
_enableFilter = widget.enableFilter;
filteredEntries = widget.dropdownMenuEntries;
+ buttonItemKeys = List<GlobalKey>.generate(filteredEntries.length, (int index) => GlobalKey());
_menuHasEnabledItem = filteredEntries.any((DropdownMenuEntry<T> entry) => entry.enabled);
final int index = filteredEntries.indexWhere((DropdownMenuEntry<T> entry) => entry.value == widget.initialSelection);
@@ -313,7 +331,15 @@
@override
void didUpdateWidget(DropdownMenu<T> oldWidget) {
super.didUpdateWidget(oldWidget);
+ if (oldWidget.enableSearch != widget.enableSearch) {
+ if (!widget.enableSearch) {
+ currentHighlight = null;
+ }
+ }
if (oldWidget.dropdownMenuEntries != widget.dropdownMenuEntries) {
+ currentHighlight = null;
+ filteredEntries = widget.dropdownMenuEntries;
+ buttonItemKeys = List<GlobalKey>.generate(filteredEntries.length, (int index) => GlobalKey());
_menuHasEnabledItem = filteredEntries.any((DropdownMenuEntry<T> entry) => entry.enabled);
}
if (oldWidget.leadingIcon != widget.leadingIcon) {
@@ -354,11 +380,20 @@
});
}
+ void scrollToHighlight() {
+ WidgetsBinding.instance.addPostFrameCallback((_) {
+ final BuildContext? highlightContext = buttonItemKeys[currentHighlight!].currentContext;
+ if (highlightContext != null) {
+ Scrollable.ensureVisible(highlightContext);
+ }
+ });
+ }
+
double? getWidth(GlobalKey key) {
final BuildContext? context = key.currentContext;
if (context != null) {
final RenderBox box = context.findRenderObject()! as RenderBox;
- return box.size.width;
+ return box.hasSize ? box.size.width : null;
}
return null;
}
@@ -384,7 +419,7 @@
List<DropdownMenuEntry<T>> filteredEntries,
TextEditingController textEditingController,
TextDirection textDirection,
- { int? focusedIndex }
+ { int? focusedIndex, bool enableScrollToHighlight = true}
) {
final List<Widget> result = <Widget>[];
final double padding = leadingPadding ?? _kDefaultHorizontalPadding;
@@ -416,6 +451,7 @@
: effectiveStyle;
final MenuItemButton menuItemButton = MenuItemButton(
+ key: enableScrollToHighlight ? buttonItemKeys[i] : null,
style: effectiveStyle,
leadingIcon: entry.leadingIcon,
trailingIcon: entry.trailingIcon,
@@ -490,7 +526,7 @@
@override
Widget build(BuildContext context) {
final TextDirection textDirection = Directionality.of(context);
- _initialMenu ??= _buildButtons(widget.dropdownMenuEntries, _textEditingController, textDirection);
+ _initialMenu ??= _buildButtons(widget.dropdownMenuEntries, _textEditingController, textDirection, enableScrollToHighlight: false);
final DropdownMenuThemeData theme = DropdownMenuTheme.of(context);
final DropdownMenuThemeData defaults = _DropdownMenuDefaultsM3(context);
@@ -500,6 +536,9 @@
if (widget.enableSearch) {
currentHighlight = search(filteredEntries, _textEditingController);
+ if (currentHighlight != null) {
+ scrollToHighlight();
+ }
}
final List<Widget> menu = _buildButtons(filteredEntries, _textEditingController, textDirection, focusedIndex: currentHighlight);
@@ -526,6 +565,108 @@
final MouseCursor effectiveMouseCursor = canRequestFocus() ? SystemMouseCursors.text : SystemMouseCursors.click;
+ Widget menuAnchor = MenuAnchor(
+ style: effectiveMenuStyle,
+ controller: _controller,
+ menuChildren: menu,
+ crossAxisUnconstrained: false,
+ builder: (BuildContext context, MenuController controller, Widget? child) {
+ assert(_initialMenu != null);
+ final Widget trailingButton = Padding(
+ padding: const EdgeInsets.all(4.0),
+ child: IconButton(
+ isSelected: controller.isOpen,
+ icon: widget.trailingIcon ?? const Icon(Icons.arrow_drop_down),
+ selectedIcon: widget.selectedTrailingIcon ?? const Icon(Icons.arrow_drop_up),
+ onPressed: () {
+ handlePressed(controller);
+ },
+ ),
+ );
+
+ final Widget leadingButton = Padding(
+ padding: const EdgeInsets.all(8.0),
+ child: widget.leadingIcon ?? const SizedBox()
+ );
+
+ final Widget textField = TextField(
+ key: _anchorKey,
+ mouseCursor: effectiveMouseCursor,
+ canRequestFocus: canRequestFocus(),
+ enableInteractiveSelection: canRequestFocus(),
+ textAlignVertical: TextAlignVertical.center,
+ style: effectiveTextStyle,
+ controller: _textEditingController,
+ onEditingComplete: () {
+ if (currentHighlight != null) {
+ final DropdownMenuEntry<T> entry = filteredEntries[currentHighlight!];
+ if (entry.enabled) {
+ _textEditingController.text = entry.label;
+ _textEditingController.selection =
+ TextSelection.collapsed(offset: _textEditingController.text.length);
+ widget.onSelected?.call(entry.value);
+ }
+ } else {
+ widget.onSelected?.call(null);
+ }
+ if (!widget.enableSearch) {
+ currentHighlight = null;
+ }
+ if (_textEditingController.text.isNotEmpty) {
+ controller.close();
+ }
+ },
+ onTap: () {
+ handlePressed(controller);
+ },
+ onChanged: (String text) {
+ controller.open();
+ setState(() {
+ filteredEntries = widget.dropdownMenuEntries;
+ _enableFilter = widget.enableFilter;
+ });
+ },
+ decoration: InputDecoration(
+ enabled: widget.enabled,
+ label: widget.label,
+ hintText: widget.hintText,
+ helperText: widget.helperText,
+ errorText: widget.errorText,
+ prefixIcon: widget.leadingIcon != null ? Container(
+ key: _leadingKey,
+ child: widget.leadingIcon
+ ) : null,
+ suffixIcon: trailingButton,
+ ).applyDefaults(effectiveInputDecorationTheme)
+ );
+
+ if (widget.expandedInsets != null) {
+ // If [expandedInsets] is not null, the width of the text field should depend
+ // on its parent width. So we don't need to use `_DropdownMenuBody` to
+ // calculate the children's width.
+ return textField;
+ }
+
+ return _DropdownMenuBody(
+ width: widget.width,
+ children: <Widget>[
+ textField,
+ for (final Widget item in _initialMenu!) item,
+ trailingButton,
+ leadingButton,
+ ],
+ );
+ },
+ );
+
+ if (widget.expandedInsets != null) {
+ menuAnchor = Container(
+ alignment: AlignmentDirectional.topStart,
+ padding: widget.expandedInsets?.copyWith(top: 0.0, bottom: 0.0),
+ child: menuAnchor,
+ );
+ }
+
return Shortcuts(
shortcuts: _kMenuTraversalShortcuts,
child: Actions(
@@ -537,90 +678,7 @@
onInvoke: handleDownKeyInvoke,
),
},
- child: MenuAnchor(
- style: effectiveMenuStyle,
- controller: _controller,
- menuChildren: menu,
- crossAxisUnconstrained: false,
- builder: (BuildContext context, MenuController controller, Widget? child) {
- assert(_initialMenu != null);
- final Widget trailingButton = Padding(
- padding: const EdgeInsets.all(4.0),
- child: IconButton(
- isSelected: controller.isOpen,
- icon: widget.trailingIcon ?? const Icon(Icons.arrow_drop_down),
- selectedIcon: widget.selectedTrailingIcon ?? const Icon(Icons.arrow_drop_up),
- onPressed: () {
- handlePressed(controller);
- },
- ),
- );
-
- final Widget leadingButton = Padding(
- padding: const EdgeInsets.all(8.0),
- child: widget.leadingIcon ?? const SizedBox()
- );
-
- return _DropdownMenuBody(
- width: widget.width,
- children: <Widget>[
- TextField(
- key: _anchorKey,
- mouseCursor: effectiveMouseCursor,
- canRequestFocus: canRequestFocus(),
- enableInteractiveSelection: canRequestFocus(),
- textAlignVertical: TextAlignVertical.center,
- style: effectiveTextStyle,
- controller: _textEditingController,
- onEditingComplete: () {
- if (currentHighlight != null) {
- final DropdownMenuEntry<T> entry = filteredEntries[currentHighlight!];
- if (entry.enabled) {
- _textEditingController.text = entry.label;
- _textEditingController.selection =
- TextSelection.collapsed(offset: _textEditingController.text.length);
- widget.onSelected?.call(entry.value);
- }
- } else {
- widget.onSelected?.call(null);
- }
- if (!widget.enableSearch) {
- currentHighlight = null;
- }
- if (_textEditingController.text.isNotEmpty) {
- controller.close();
- }
- },
- onTap: () {
- handlePressed(controller);
- },
- onChanged: (String text) {
- controller.open();
- setState(() {
- filteredEntries = widget.dropdownMenuEntries;
- _enableFilter = widget.enableFilter;
- });
- },
- decoration: InputDecoration(
- enabled: widget.enabled,
- label: widget.label,
- hintText: widget.hintText,
- helperText: widget.helperText,
- errorText: widget.errorText,
- prefixIcon: widget.leadingIcon != null ? Container(
- key: _leadingKey,
- child: widget.leadingIcon
- ) : null,
- suffixIcon: trailingButton,
- ).applyDefaults(effectiveInputDecorationTheme)
- ),
- for (final Widget c in _initialMenu!) c,
- trailingButton,
- leadingButton,
- ],
- );
- },
- ),
+ child: menuAnchor,
),
);
}
diff --git a/packages/flutter/lib/src/material/expansion_tile.dart b/packages/flutter/lib/src/material/expansion_tile.dart
index 10ca52d..3dc8e99 100644
--- a/packages/flutter/lib/src/material/expansion_tile.dart
+++ b/packages/flutter/lib/src/material/expansion_tile.dart
@@ -683,7 +683,7 @@
bottom: BorderSide(color: Colors.transparent),
)
..end = widget.shape
- ?? expansionTileTheme.collapsedShape
+ ?? expansionTileTheme.shape
?? Border(
top: BorderSide(color: theme.dividerColor),
bottom: BorderSide(color: theme.dividerColor),
diff --git a/packages/flutter/lib/src/material/filter_chip.dart b/packages/flutter/lib/src/material/filter_chip.dart
index 6753847..887bb05 100644
--- a/packages/flutter/lib/src/material/filter_chip.dart
+++ b/packages/flutter/lib/src/material/filter_chip.dart
@@ -10,6 +10,7 @@
import 'color_scheme.dart';
import 'colors.dart';
import 'debug.dart';
+import 'material_state.dart';
import 'text_theme.dart';
import 'theme.dart';
import 'theme_data.dart';
@@ -80,6 +81,7 @@
this.clipBehavior = Clip.none,
this.focusNode,
this.autofocus = false,
+ this.color,
this.backgroundColor,
this.padding,
this.visualDensity,
@@ -118,6 +120,7 @@
this.clipBehavior = Clip.none,
this.focusNode,
this.autofocus = false,
+ this.color,
this.backgroundColor,
this.padding,
this.visualDensity,
@@ -165,6 +168,8 @@
@override
final bool autofocus;
@override
+ final MaterialStateProperty<Color?>? color;
+ @override
final Color? backgroundColor;
@override
final EdgeInsetsGeometry? padding;
@@ -215,6 +220,7 @@
clipBehavior: clipBehavior,
focusNode: focusNode,
autofocus: autofocus,
+ color: color,
backgroundColor: backgroundColor,
disabledColor: disabledColor,
selectedColor: selectedColor,
@@ -270,7 +276,27 @@
TextStyle? get labelStyle => _textTheme.labelLarge;
@override
- Color? get backgroundColor => null;
+ MaterialStateProperty<Color?>? get color =>
+ MaterialStateProperty.resolveWith((Set<MaterialState> states) {
+ if (states.contains(MaterialState.selected) && states.contains(MaterialState.disabled)) {
+ return _chipVariant == _ChipVariant.flat
+ ? _colors.onSurface.withOpacity(0.12)
+ : _colors.onSurface.withOpacity(0.12);
+ }
+ if (states.contains(MaterialState.disabled)) {
+ return _chipVariant == _ChipVariant.flat
+ ? null
+ : _colors.onSurface.withOpacity(0.12);
+ }
+ if (states.contains(MaterialState.selected)) {
+ return _chipVariant == _ChipVariant.flat
+ ? _colors.secondaryContainer
+ : _colors.secondaryContainer;
+ }
+ return _chipVariant == _ChipVariant.flat
+ ? null
+ : null;
+ });
@override
Color? get shadowColor => _chipVariant == _ChipVariant.flat
@@ -281,25 +307,9 @@
Color? get surfaceTintColor => _colors.surfaceTint;
@override
- Color? get selectedColor => _chipVariant == _ChipVariant.flat
- ? isEnabled
- ? _colors.secondaryContainer
- : _colors.onSurface.withOpacity(0.12)
- : isEnabled
- ? _colors.secondaryContainer
- : _colors.onSurface.withOpacity(0.12);
-
- @override
Color? get checkmarkColor => _colors.onSecondaryContainer;
@override
- Color? get disabledColor => _chipVariant == _ChipVariant.flat
- ? isSelected
- ? _colors.onSurface.withOpacity(0.12)
- : null
- : _colors.onSurface.withOpacity(0.12);
-
- @override
Color? get deleteIconColor => _colors.onSecondaryContainer;
@override
diff --git a/packages/flutter/lib/src/material/flexible_space_bar.dart b/packages/flutter/lib/src/material/flexible_space_bar.dart
index e187fd6..3b3fd35 100644
--- a/packages/flutter/lib/src/material/flexible_space_bar.dart
+++ b/packages/flutter/lib/src/material/flexible_space_bar.dart
@@ -451,4 +451,21 @@
@override
bool get isRepaintBoundary => false;
+
+ @override
+ void paint(PaintingContext context, Offset offset) {
+ if (child == null) {
+ return;
+ }
+ if (opacity == 0) {
+ layer = null;
+ return;
+ }
+ assert(needsCompositing);
+ layer = context.pushOpacity(offset, (opacity * 255).round(), super.paint, oldLayer: layer as OpacityLayer?);
+ assert(() {
+ layer!.debugCreator = debugCreator;
+ return true;
+ }());
+ }
}
diff --git a/packages/flutter/lib/src/material/input_chip.dart b/packages/flutter/lib/src/material/input_chip.dart
index 53974e4..756d557 100644
--- a/packages/flutter/lib/src/material/input_chip.dart
+++ b/packages/flutter/lib/src/material/input_chip.dart
@@ -11,6 +11,7 @@
import 'colors.dart';
import 'debug.dart';
import 'icons.dart';
+import 'material_state.dart';
import 'text_theme.dart';
import 'theme.dart';
import 'theme_data.dart';
@@ -99,6 +100,7 @@
this.clipBehavior = Clip.none,
this.focusNode,
this.autofocus = false,
+ this.color,
this.backgroundColor,
this.padding,
this.visualDensity,
@@ -162,6 +164,8 @@
@override
final bool autofocus;
@override
+ final MaterialStateProperty<Color?>? color;
+ @override
final Color? backgroundColor;
@override
final EdgeInsetsGeometry? padding;
@@ -223,6 +227,7 @@
clipBehavior: clipBehavior,
focusNode: focusNode,
autofocus: autofocus,
+ color: color,
backgroundColor: backgroundColor,
padding: padding,
visualDensity: visualDensity,
@@ -264,7 +269,19 @@
TextStyle? get labelStyle => _textTheme.labelLarge;
@override
- Color? get backgroundColor => null;
+ MaterialStateProperty<Color?>? get color =>
+ MaterialStateProperty.resolveWith((Set<MaterialState> states) {
+ if (states.contains(MaterialState.selected) && states.contains(MaterialState.disabled)) {
+ return _colors.onSurface.withOpacity(0.12);
+ }
+ if (states.contains(MaterialState.disabled)) {
+ return null;
+ }
+ if (states.contains(MaterialState.selected)) {
+ return _colors.secondaryContainer;
+ }
+ return null;
+ });
@override
Color? get shadowColor => Colors.transparent;
@@ -273,17 +290,9 @@
Color? get surfaceTintColor => Colors.transparent;
@override
- Color? get selectedColor => isEnabled
- ? _colors.secondaryContainer
- : _colors.onSurface.withOpacity(0.12);
-
- @override
Color? get checkmarkColor => null;
@override
- Color? get disabledColor => null;
-
- @override
Color? get deleteIconColor => _colors.onSecondaryContainer;
@override
diff --git a/packages/flutter/lib/src/material/input_date_picker_form_field.dart b/packages/flutter/lib/src/material/input_date_picker_form_field.dart
index 460ebee..4a82273 100644
--- a/packages/flutter/lib/src/material/input_date_picker_form_field.dart
+++ b/packages/flutter/lib/src/material/input_date_picker_form_field.dart
@@ -5,6 +5,7 @@
import 'package:flutter/widgets.dart';
import 'date.dart';
+import 'date_picker_theme.dart';
import 'input_border.dart';
import 'input_decorator.dart';
import 'material_localizations.dart';
@@ -248,16 +249,19 @@
final ThemeData theme = Theme.of(context);
final bool useMaterial3 = theme.useMaterial3;
final MaterialLocalizations localizations = MaterialLocalizations.of(context);
+ final DatePickerThemeData datePickerTheme = theme.datePickerTheme;
final InputDecorationTheme inputTheme = theme.inputDecorationTheme;
- final InputBorder inputBorder = inputTheme.border
+ final InputBorder effectiveInputBorder = datePickerTheme.inputDecorationTheme?.border
+ ?? theme.inputDecorationTheme.border
?? (useMaterial3 ? const OutlineInputBorder() : const UnderlineInputBorder());
return TextFormField(
decoration: InputDecoration(
- border: inputBorder,
- filled: inputTheme.filled,
hintText: widget.fieldHintText ?? localizations.dateHelpText,
labelText: widget.fieldLabelText ?? localizations.dateInputLabel,
+ ).applyDefaults(inputTheme
+ .merge(datePickerTheme.inputDecorationTheme)
+ .copyWith(border: effectiveInputBorder),
),
validator: _validateDate,
keyboardType: widget.keyboardType ?? TextInputType.datetime,
diff --git a/packages/flutter/lib/src/material/input_decorator.dart b/packages/flutter/lib/src/material/input_decorator.dart
index c55ac42..d957c7a 100644
--- a/packages/flutter/lib/src/material/input_decorator.dart
+++ b/packages/flutter/lib/src/material/input_decorator.dart
@@ -302,6 +302,7 @@
this.helperText,
this.helperStyle,
this.helperMaxLines,
+ this.error,
this.errorText,
this.errorStyle,
this.errorMaxLines,
@@ -311,6 +312,7 @@
final String? helperText;
final TextStyle? helperStyle;
final int? helperMaxLines;
+ final Widget? error;
final String? errorText;
final TextStyle? errorStyle;
final int? errorMaxLines;
@@ -328,6 +330,8 @@
Widget? _helper;
Widget? _error;
+ bool get _hasError => widget.errorText != null || widget.error != null;
+
@override
void initState() {
super.initState();
@@ -335,7 +339,7 @@
duration: _kTransitionDuration,
vsync: this,
);
- if (widget.errorText != null) {
+ if (_hasError) {
_error = _buildError();
_controller.value = 1.0;
} else if (widget.helperText != null) {
@@ -360,16 +364,19 @@
void didUpdateWidget(_HelperError old) {
super.didUpdateWidget(old);
+ final Widget? newError = widget.error;
final String? newErrorText = widget.errorText;
final String? newHelperText = widget.helperText;
+ final Widget? oldError = old.error;
final String? oldErrorText = old.errorText;
final String? oldHelperText = old.helperText;
+ final bool errorStateChanged = (newError != null) != (oldError != null);
final bool errorTextStateChanged = (newErrorText != null) != (oldErrorText != null);
final bool helperTextStateChanged = newErrorText == null && (newHelperText != null) != (oldHelperText != null);
- if (errorTextStateChanged || helperTextStateChanged) {
- if (newErrorText != null) {
+ if (errorStateChanged || errorTextStateChanged || helperTextStateChanged) {
+ if (newError != null || newErrorText != null) {
_error = _buildError();
_controller.forward();
} else if (newHelperText != null) {
@@ -399,7 +406,7 @@
}
Widget _buildError() {
- assert(widget.errorText != null);
+ assert(widget.error != null || widget.errorText != null);
return Semantics(
container: true,
child: FadeTransition(
@@ -409,7 +416,7 @@
begin: const Offset(0.0, -0.25),
end: Offset.zero,
).evaluate(_controller.view),
- child: Text(
+ child: widget.error ?? Text(
widget.errorText!,
style: widget.errorStyle,
textAlign: widget.textAlign,
@@ -435,7 +442,7 @@
if (_controller.isCompleted) {
_helper = null;
- if (widget.errorText != null) {
+ if (_hasError) {
return _error = _buildError();
} else {
_error = null;
@@ -443,7 +450,7 @@
}
}
- if (_helper == null && widget.errorText != null) {
+ if (_helper == null && _hasError) {
return _buildError();
}
@@ -451,7 +458,7 @@
return _buildHelper();
}
- if (widget.errorText != null) {
+ if (_hasError) {
return Stack(
children: <Widget>[
FadeTransition(
@@ -1403,7 +1410,7 @@
double start = right - _boxSize(icon).width;
double end = left;
if (prefixIcon != null) {
- start += contentPadding.left;
+ start += contentPadding.right;
start -= centerLayout(prefixIcon!, start - prefixIcon!.size.width);
}
if (label != null) {
@@ -2365,6 +2372,7 @@
helperText: decoration.helperText,
helperStyle: _getHelperStyle(themeData, defaults),
helperMaxLines: decoration.helperMaxLines,
+ error: decoration.error,
errorText: decoration.errorText,
errorStyle: _getErrorStyle(themeData, defaults),
errorMaxLines: decoration.errorMaxLines,
@@ -2562,6 +2570,7 @@
this.hintStyle,
this.hintTextDirection,
this.hintMaxLines,
+ this.error,
this.errorText,
this.errorStyle,
this.errorMaxLines,
@@ -2601,7 +2610,8 @@
this.constraints,
}) : assert(!(label != null && labelText != null), 'Declaring both label and labelText is not supported.'),
assert(!(prefix != null && prefixText != null), 'Declaring both prefix and prefixText is not supported.'),
- assert(!(suffix != null && suffixText != null), 'Declaring both suffix and suffixText is not supported.');
+ assert(!(suffix != null && suffixText != null), 'Declaring both suffix and suffixText is not supported.'),
+ assert(!(error != null && errorText != null), 'Declaring both error and errorText is not supported.');
/// Defines an [InputDecorator] that is the same size as the input field.
///
@@ -2630,6 +2640,7 @@
helperStyle = null,
helperMaxLines = null,
hintMaxLines = null,
+ error = null,
errorText = null,
errorStyle = null,
errorMaxLines = null,
@@ -2842,6 +2853,13 @@
/// used to handle the overflow when it is limited to single line.
final int? hintMaxLines;
+ /// Optional widget that appears below the [InputDecorator.child] and the border.
+ ///
+ /// If non-null, the border's color animates to red and the [helperText] is not shown.
+ ///
+ /// Only one of [error] and [errorText] can be specified.
+ final Widget? error;
+
/// Text that appears below the [InputDecorator.child] and the border.
///
/// If non-null, the border's color animates to red and the [helperText] is
@@ -2849,6 +2867,10 @@
///
/// In a [TextFormField], this is overridden by the value returned from
/// [TextFormField.validator], if that is not null.
+ ///
+ /// If a more elaborate error is required, consider using [error] instead.
+ ///
+ /// Only one of [error] and [errorText] can be specified.
final String? errorText;
/// {@template flutter.material.inputDecoration.errorStyle}
@@ -3485,6 +3507,7 @@
TextStyle? hintStyle,
TextDirection? hintTextDirection,
int? hintMaxLines,
+ Widget? error,
String? errorText,
TextStyle? errorStyle,
int? errorMaxLines,
@@ -3537,6 +3560,7 @@
hintStyle: hintStyle ?? this.hintStyle,
hintTextDirection: hintTextDirection ?? this.hintTextDirection,
hintMaxLines: hintMaxLines ?? this.hintMaxLines,
+ error: error ?? this.error,
errorText: errorText ?? this.errorText,
errorStyle: errorStyle ?? this.errorStyle,
errorMaxLines: errorMaxLines ?? this.errorMaxLines,
@@ -3593,11 +3617,14 @@
errorMaxLines: errorMaxLines ?? theme.errorMaxLines,
floatingLabelBehavior: floatingLabelBehavior ?? theme.floatingLabelBehavior,
floatingLabelAlignment: floatingLabelAlignment ?? theme.floatingLabelAlignment,
- isCollapsed: isCollapsed,
isDense: isDense ?? theme.isDense,
contentPadding: contentPadding ?? theme.contentPadding,
+ isCollapsed: isCollapsed,
+ iconColor: iconColor ?? theme.iconColor,
prefixStyle: prefixStyle ?? theme.prefixStyle,
+ prefixIconColor: prefixIconColor ?? theme.prefixIconColor,
suffixStyle: suffixStyle ?? theme.suffixStyle,
+ suffixIconColor: suffixIconColor ?? theme.suffixIconColor,
counterStyle: counterStyle ?? theme.counterStyle,
filled: filled ?? theme.filled,
fillColor: fillColor ?? theme.fillColor,
@@ -3636,6 +3663,7 @@
&& other.hintStyle == hintStyle
&& other.hintTextDirection == hintTextDirection
&& other.hintMaxLines == hintMaxLines
+ && other.error == error
&& other.errorText == errorText
&& other.errorStyle == errorStyle
&& other.errorMaxLines == errorMaxLines
@@ -3691,6 +3719,7 @@
hintStyle,
hintTextDirection,
hintMaxLines,
+ error,
errorText,
errorStyle,
errorMaxLines,
@@ -3744,6 +3773,7 @@
if (helperMaxLines != null) 'helperMaxLines: "$helperMaxLines"',
if (hintText != null) 'hintText: "$hintText"',
if (hintMaxLines != null) 'hintMaxLines: "$hintMaxLines"',
+ if (error != null) 'error: "$error"',
if (errorText != null) 'errorText: "$errorText"',
if (errorStyle != null) 'errorStyle: "$errorStyle"',
if (errorMaxLines != null) 'errorMaxLines: "$errorMaxLines"',
@@ -4279,6 +4309,49 @@
);
}
+ /// Returns a copy of this InputDecorationTheme where the non-null fields in
+ /// the given InputDecorationTheme override the corresponding nullable fields
+ /// in this InputDecorationTheme.
+ ///
+ /// The non-nullable fields of InputDecorationTheme, such as [floatingLabelBehavior],
+ /// [isDense], [isCollapsed], [filled], and [alignLabelWithHint] cannot be overridden.
+ ///
+ /// In other words, the fields of the provided [InputDecorationTheme] are used to
+ /// fill in the unspecified and nullable fields of this InputDecorationTheme.
+ InputDecorationTheme merge(InputDecorationTheme? inputDecorationTheme) {
+ if (inputDecorationTheme == null) {
+ return this;
+ }
+ return copyWith(
+ labelStyle: labelStyle ?? inputDecorationTheme.labelStyle,
+ floatingLabelStyle: floatingLabelStyle ?? inputDecorationTheme.floatingLabelStyle,
+ helperStyle: helperStyle ?? inputDecorationTheme.helperStyle,
+ helperMaxLines: helperMaxLines ?? inputDecorationTheme.helperMaxLines,
+ hintStyle: hintStyle ?? inputDecorationTheme.hintStyle,
+ errorStyle: errorStyle ?? inputDecorationTheme.errorStyle,
+ errorMaxLines: errorMaxLines ?? inputDecorationTheme.errorMaxLines,
+ contentPadding: contentPadding ?? inputDecorationTheme.contentPadding,
+ iconColor: iconColor ?? inputDecorationTheme.iconColor,
+ prefixStyle: prefixStyle ?? inputDecorationTheme.prefixStyle,
+ prefixIconColor: prefixIconColor ?? inputDecorationTheme.prefixIconColor,
+ suffixStyle: suffixStyle ?? inputDecorationTheme.suffixStyle,
+ suffixIconColor: suffixIconColor ?? inputDecorationTheme.suffixIconColor,
+ counterStyle: counterStyle ?? inputDecorationTheme.counterStyle,
+ fillColor: fillColor ?? inputDecorationTheme.fillColor,
+ activeIndicatorBorder: activeIndicatorBorder ?? inputDecorationTheme.activeIndicatorBorder,
+ outlineBorder: outlineBorder ?? inputDecorationTheme.outlineBorder,
+ focusColor: focusColor ?? inputDecorationTheme.focusColor,
+ hoverColor: hoverColor ?? inputDecorationTheme.hoverColor,
+ errorBorder: errorBorder ?? inputDecorationTheme.errorBorder,
+ focusedBorder: focusedBorder ?? inputDecorationTheme.focusedBorder,
+ focusedErrorBorder: focusedErrorBorder ?? inputDecorationTheme.focusedErrorBorder,
+ disabledBorder: disabledBorder ?? inputDecorationTheme.disabledBorder,
+ enabledBorder: enabledBorder ?? inputDecorationTheme.enabledBorder,
+ border: border ?? inputDecorationTheme.border,
+ constraints: constraints ?? inputDecorationTheme.constraints,
+ );
+ }
+
@override
int get hashCode => Object.hash(
labelStyle,
diff --git a/packages/flutter/lib/src/material/material.dart b/packages/flutter/lib/src/material/material.dart
index 5d8ccf4..e7d76a4 100644
--- a/packages/flutter/lib/src/material/material.dart
+++ b/packages/flutter/lib/src/material/material.dart
@@ -762,7 +762,7 @@
final int toDepth = to.depth;
if (fromDepth >= toDepth) {
- final AbstractNode? fromParent = from.parent;
+ final RenderObject? fromParent = from.parent;
// Return early if the 2 render objects are not in the same render tree,
// or either of them is offscreen and thus won't get painted.
if (fromParent is! RenderObject || !fromParent.paintsChild(from)) {
@@ -773,7 +773,7 @@
}
if (fromDepth <= toDepth) {
- final AbstractNode? toParent = to.parent;
+ final RenderObject? toParent = to.parent;
if (toParent is! RenderObject || !toParent.paintsChild(to)) {
return null;
}
diff --git a/packages/flutter/lib/src/material/material_localizations.dart b/packages/flutter/lib/src/material/material_localizations.dart
index d2286a4..489c23a 100644
--- a/packages/flutter/lib/src/material/material_localizations.dart
+++ b/packages/flutter/lib/src/material/material_localizations.dart
@@ -103,6 +103,9 @@
/// Label for "cut" edit buttons and menu items.
String get cutButtonLabel;
+ /// Label for "scan text" OCR edit buttons and menu items.
+ String get scanTextButtonLabel;
+
/// Label for OK buttons and menu items.
String get okButtonLabel;
@@ -1160,6 +1163,9 @@
String get cutButtonLabel => 'Cut';
@override
+ String get scanTextButtonLabel => 'Scan text';
+
+ @override
String get okButtonLabel => 'OK';
@override
diff --git a/packages/flutter/lib/src/material/mergeable_material.dart b/packages/flutter/lib/src/material/mergeable_material.dart
index da1af3b..1ff2982 100644
--- a/packages/flutter/lib/src/material/mergeable_material.dart
+++ b/packages/flutter/lib/src/material/mergeable_material.dart
@@ -470,7 +470,12 @@
_removeChild(j);
}
while (i < newChildren.length) {
- _insertChild(j, newChildren[i]);
+ final MergeableMaterialItem newChild = newChildren[i];
+ _insertChild(j, newChild);
+
+ if (newChild is MaterialGap) {
+ _animationTuples[newChild.key]!.controller.forward();
+ }
i += 1;
j += 1;
diff --git a/packages/flutter/lib/src/material/navigation_drawer.dart b/packages/flutter/lib/src/material/navigation_drawer.dart
index 1accb3a..f52e202 100644
--- a/packages/flutter/lib/src/material/navigation_drawer.dart
+++ b/packages/flutter/lib/src/material/navigation_drawer.dart
@@ -218,7 +218,7 @@
///
/// The icon will use [NavigationDrawerThemeData.iconTheme] with
/// [MaterialState.selected]. If this is null, the default [IconThemeData]
- /// would use a size of 24.0 and [ColorScheme.onSurfaceVariant].
+ /// would use a size of 24.0 and [ColorScheme.onSecondaryContainer].
final Widget? selectedIcon;
/// The text label that appears on the right of the icon
@@ -702,7 +702,7 @@
return IconThemeData(
size: 24.0,
color: states.contains(MaterialState.selected)
- ? null
+ ? _colors.onSecondaryContainer
: _colors.onSurfaceVariant,
);
});
diff --git a/packages/flutter/lib/src/material/scaffold.dart b/packages/flutter/lib/src/material/scaffold.dart
index 7d40251..110cbbb 100644
--- a/packages/flutter/lib/src/material/scaffold.dart
+++ b/packages/flutter/lib/src/material/scaffold.dart
@@ -279,6 +279,12 @@
/// the SnackBar to be visible.
///
/// {@tool dartpad}
+ /// Here is an example showing how to display a [SnackBar] with [showSnackBar]
+ ///
+ /// ** See code in examples/api/lib/material/scaffold/scaffold_messenger_state.show_snack_bar.0.dart **
+ /// {@end-tool}
+ ///
+ /// {@tool dartpad}
/// Here is an example showing that a floating [SnackBar] appears above [Scaffold.floatingActionButton].
///
/// ** See code in examples/api/lib/material/scaffold/scaffold_messenger_state.show_snack_bar.1.dart **
@@ -1358,11 +1364,9 @@
void _handlePreviousAnimationStatusChanged(AnimationStatus status) {
setState(() {
- if (status == AnimationStatus.dismissed) {
+ if (widget.child != null && status == AnimationStatus.dismissed) {
assert(widget.currentController.status == AnimationStatus.dismissed);
- if (widget.child != null) {
- widget.currentController.forward();
- }
+ widget.currentController.forward();
}
});
}
diff --git a/packages/flutter/lib/src/material/search.dart b/packages/flutter/lib/src/material/search.dart
index ab7eee7..e465c54 100644
--- a/packages/flutter/lib/src/material/search.dart
+++ b/packages/flutter/lib/src/material/search.dart
@@ -211,6 +211,15 @@
///
PreferredSizeWidget? buildBottom(BuildContext context) => null;
+ /// Widget to display a flexible space in the [AppBar].
+ ///
+ /// Returns null by default, i.e. a flexible space widget is not included.
+ ///
+ /// See also:
+ ///
+ /// * [AppBar.flexibleSpace], the intended use for the return value of this method.
+ Widget? buildFlexibleSpace(BuildContext context) => null;
+
/// The theme used to configure the search page.
///
/// The returned [ThemeData] will be used to wrap the entire search page,
@@ -581,11 +590,10 @@
style: widget.delegate.searchFieldStyle ?? theme.textTheme.titleLarge,
textInputAction: widget.delegate.textInputAction,
keyboardType: widget.delegate.keyboardType,
- onSubmitted: (String _) {
- widget.delegate.showResults(context);
- },
+ onSubmitted: (String _) => widget.delegate.showResults(context),
decoration: InputDecoration(hintText: searchFieldLabel),
),
+ flexibleSpace: widget.delegate.buildFlexibleSpace(context),
actions: widget.delegate.buildActions(context),
bottom: widget.delegate.buildBottom(context),
),
diff --git a/packages/flutter/lib/src/material/search_anchor.dart b/packages/flutter/lib/src/material/search_anchor.dart
index 89c69ff..fbb4682 100644
--- a/packages/flutter/lib/src/material/search_anchor.dart
+++ b/packages/flutter/lib/src/material/search_anchor.dart
@@ -87,6 +87,19 @@
/// ** See code in examples/api/lib/material/search_anchor/search_anchor.1.dart **
/// {@end-tool}
///
+/// {@tool dartpad}
+/// This example shows how to fetch the search suggestions from a remote API.
+///
+/// ** See code in examples/api/lib/material/search_anchor/search_anchor.3.dart **
+/// {@end-tool}
+///
+/// {@tool dartpad}
+/// This example demonstrates fetching the search suggestions asynchronously and
+/// debouncing network calls.
+///
+/// ** See code in examples/api/lib/material/search_anchor/search_anchor.4.dart **
+/// {@end-tool}
+///
/// See also:
///
/// * [SearchBar], a widget that defines a search bar.
@@ -489,7 +502,8 @@
}
void updateTweens(BuildContext context) {
- final Size screenSize = MediaQuery.of(context).size;
+ final RenderBox navigator = Navigator.of(context).context.findRenderObject()! as RenderBox;
+ final Size screenSize = navigator.size;
final Rect anchorRect = getRect() ?? Rect.zero;
final BoxConstraints effectiveConstraints = viewConstraints ?? viewTheme.constraints ?? viewDefaults.constraints!;
@@ -996,6 +1010,7 @@
this.trailing,
this.onTap,
this.onChanged,
+ this.onSubmitted,
this.constraints,
this.elevation,
this.backgroundColor,
@@ -1044,6 +1059,10 @@
/// Invoked upon user input.
final ValueChanged<String>? onChanged;
+ /// Called when the user indicates that they are done editing the text in the
+ /// field.
+ final ValueChanged<String>? onSubmitted;
+
/// Optional size constraints for the search bar.
///
/// If null, the value of [SearchBarThemeData.constraints] will be used. If
@@ -1236,6 +1255,7 @@
child: TextField(
focusNode: _focusNode,
onChanged: widget.onChanged,
+ onSubmitted: widget.onSubmitted,
controller: widget.controller,
style: effectiveTextStyle,
decoration: InputDecoration(
diff --git a/packages/flutter/lib/src/material/selection_area.dart b/packages/flutter/lib/src/material/selection_area.dart
index 625f3aa..2334f54 100644
--- a/packages/flutter/lib/src/material/selection_area.dart
+++ b/packages/flutter/lib/src/material/selection_area.dart
@@ -103,13 +103,7 @@
}
class _SelectionAreaState extends State<SelectionArea> {
- FocusNode get _effectiveFocusNode {
- if (widget.focusNode != null) {
- return widget.focusNode!;
- }
- _internalNode ??= FocusNode();
- return _internalNode!;
- }
+ FocusNode get _effectiveFocusNode => widget.focusNode ?? (_internalNode ??= FocusNode());
FocusNode? _internalNode;
@override
@@ -121,20 +115,12 @@
@override
Widget build(BuildContext context) {
assert(debugCheckHasMaterialLocalizations(context));
- TextSelectionControls? controls = widget.selectionControls;
- switch (Theme.of(context).platform) {
- case TargetPlatform.android:
- case TargetPlatform.fuchsia:
- controls ??= materialTextSelectionHandleControls;
- case TargetPlatform.iOS:
- controls ??= cupertinoTextSelectionHandleControls;
- case TargetPlatform.linux:
- case TargetPlatform.windows:
- controls ??= desktopTextSelectionHandleControls;
- case TargetPlatform.macOS:
- controls ??= cupertinoDesktopTextSelectionHandleControls;
- }
-
+ final TextSelectionControls controls = widget.selectionControls ?? switch (Theme.of(context).platform) {
+ TargetPlatform.android || TargetPlatform.fuchsia => materialTextSelectionHandleControls,
+ TargetPlatform.linux || TargetPlatform.windows => desktopTextSelectionHandleControls,
+ TargetPlatform.iOS => cupertinoTextSelectionHandleControls,
+ TargetPlatform.macOS => cupertinoDesktopTextSelectionHandleControls,
+ };
return SelectableRegion(
selectionControls: controls,
focusNode: _effectiveFocusNode,
diff --git a/packages/flutter/lib/src/material/slider.dart b/packages/flutter/lib/src/material/slider.dart
index 9790cea..6680aaa 100644
--- a/packages/flutter/lib/src/material/slider.dart
+++ b/packages/flutter/lib/src/material/slider.dart
@@ -1530,10 +1530,7 @@
onChangeEnd?.call(_discretize(_currentDragValue));
_active = false;
_currentDragValue = 0.0;
- if (!hasFocus) {
- _state.overlayController.reverse();
- }
-
+ _state.overlayController.reverse();
if (showValueIndicator && _state.interactionTimer == null) {
_state.valueIndicatorController.reverse();
}
diff --git a/packages/flutter/lib/src/material/snack_bar.dart b/packages/flutter/lib/src/material/snack_bar.dart
index de80b2b..5dea738 100644
--- a/packages/flutter/lib/src/material/snack_bar.dart
+++ b/packages/flutter/lib/src/material/snack_bar.dart
@@ -250,6 +250,13 @@
/// ** See code in examples/api/lib/material/snack_bar/snack_bar.1.dart **
/// {@end-tool}
///
+/// {@tool dartpad}
+/// This example demonstrates the various [SnackBar] widget components,
+/// including an optional icon, in either floating or fixed format.
+///
+/// ** See code in examples/api/lib/material/snack_bar/snack_bar.2.dart **
+/// {@end-tool}
+///
/// See also:
///
/// * [ScaffoldMessenger.of], to obtain the current [ScaffoldMessengerState],
@@ -842,11 +849,12 @@
@override
TextStyle? get contentTextStyle => ThemeData(
- brightness: _theme.brightness == Brightness.light
- ? Brightness.dark
- : Brightness.light)
- .textTheme
- .titleMedium;
+ useMaterial3: _theme.useMaterial3,
+ brightness: _theme.brightness == Brightness.light
+ ? Brightness.dark
+ : Brightness.light)
+ .textTheme
+ .titleMedium;
@override
SnackBarBehavior get behavior => SnackBarBehavior.fixed;
diff --git a/packages/flutter/lib/src/material/stepper.dart b/packages/flutter/lib/src/material/stepper.dart
index 3d374dd..b6ab24a 100644
--- a/packages/flutter/lib/src/material/stepper.dart
+++ b/packages/flutter/lib/src/material/stepper.dart
@@ -202,6 +202,7 @@
const Stepper({
super.key,
required this.steps,
+ this.controller,
this.physics,
this.type = StepperType.vertical,
this.currentStep = 0,
@@ -230,6 +231,13 @@
/// can be helpful to set this property to [ClampingScrollPhysics].
final ScrollPhysics? physics;
+ /// An object that can be used to control the position to which this scroll
+ /// view is scrolled.
+ ///
+ /// To control the initial scroll offset of the scroll view, provide a
+ /// [controller] with its [ScrollController.initialScrollOffset] property set.
+ final ScrollController? controller;
+
/// The type of stepper that determines the layout. In the case of
/// [StepperType.horizontal], the content of the current step is displayed
/// underneath as opposed to the [StepperType.vertical] case where it is
@@ -765,6 +773,7 @@
Widget _buildVertical() {
return ListView(
+ controller: widget.controller,
shrinkWrap: true,
physics: widget.physics,
children: <Widget>[
@@ -858,6 +867,7 @@
),
Expanded(
child: ListView(
+ controller: widget.controller,
physics: widget.physics,
padding: const EdgeInsets.all(24.0),
children: <Widget>[
diff --git a/packages/flutter/lib/src/material/switch.dart b/packages/flutter/lib/src/material/switch.dart
index 0cfc6ff..e301c85 100644
--- a/packages/flutter/lib/src/material/switch.dart
+++ b/packages/flutter/lib/src/material/switch.dart
@@ -69,6 +69,13 @@
/// ** See code in examples/api/lib/material/switch/switch.2.dart **
/// {@end-tool}
///
+/// {@tool dartpad}
+/// This example shows how to use the ambient [CupertinoThemeData] to style all
+/// widgets which would otherwise use iOS defaults.
+///
+/// ** See code in examples/api/lib/material/switch/switch.3.dart **
+/// {@end-tool}
+///
/// See also:
///
/// * [SwitchListTile], which combines this widget with a [ListTile] so that
diff --git a/packages/flutter/lib/src/material/text_field.dart b/packages/flutter/lib/src/material/text_field.dart
index f2d6716..4a3a1e5 100644
--- a/packages/flutter/lib/src/material/text_field.dart
+++ b/packages/flutter/lib/src/material/text_field.dart
@@ -178,6 +178,13 @@
///
/// {@macro flutter.widgets.editableText.accessibility}
///
+/// {@tool dartpad}
+/// This sample shows how to style a text field to match a filled or outlined
+/// Material Design 3 text field.
+///
+/// ** See code in examples/api/lib/material/text_field/text_field.2.dart **
+/// {@end-tool}
+///
/// See also:
///
/// * [TextFormField], which integrates with the [Form] widget.
diff --git a/packages/flutter/lib/src/material/tooltip.dart b/packages/flutter/lib/src/material/tooltip.dart
index ff73b26..2be81e1 100644
--- a/packages/flutter/lib/src/material/tooltip.dart
+++ b/packages/flutter/lib/src/material/tooltip.dart
@@ -425,30 +425,27 @@
// _handleMouseExit. The set is cleared in _handleTapToDismiss, typically when
// a PointerDown event interacts with some other UI component.
final Set<int> _activeHoveringPointerDevices = <int>{};
+
+ static bool _isTooltipVisible(AnimationStatus status) {
+ return switch (status) {
+ AnimationStatus.completed || AnimationStatus.forward || AnimationStatus.reverse => true,
+ AnimationStatus.dismissed => false,
+ };
+ }
+
AnimationStatus _animationStatus = AnimationStatus.dismissed;
void _handleStatusChanged(AnimationStatus status) {
assert(mounted);
- final bool entryNeedsUpdating;
- switch (status) {
- case AnimationStatus.dismissed:
- entryNeedsUpdating = _animationStatus != AnimationStatus.dismissed;
- if (entryNeedsUpdating) {
- Tooltip._openedTooltips.remove(this);
- _overlayController.hide();
- }
- case AnimationStatus.completed:
- case AnimationStatus.forward:
- case AnimationStatus.reverse:
- entryNeedsUpdating = _animationStatus == AnimationStatus.dismissed;
- if (entryNeedsUpdating) {
- _overlayController.show();
- Tooltip._openedTooltips.add(this);
- SemanticsService.tooltip(_tooltipMessage);
- }
- }
-
- if (entryNeedsUpdating) {
- setState(() { /* Rebuild to update the OverlayEntry */ });
+ switch ((_isTooltipVisible(_animationStatus), _isTooltipVisible(status))) {
+ case (true, false):
+ Tooltip._openedTooltips.remove(this);
+ _overlayController.hide();
+ case (false, true):
+ _overlayController.show();
+ Tooltip._openedTooltips.add(this);
+ SemanticsService.tooltip(_tooltipMessage);
+ case (true, true) || (false, false):
+ break;
}
_animationStatus = status;
}
@@ -485,13 +482,16 @@
void _scheduleDismissTooltip({ required Duration withDelay }) {
assert(mounted);
assert(
- !(_timer?.isActive ?? false) || _controller.status != AnimationStatus.reverse,
+ !(_timer?.isActive ?? false) || _backingController?.status != AnimationStatus.reverse,
'timer must not be active when the tooltip is fading out',
);
_timer?.cancel();
_timer = null;
- switch (_controller.status) {
+ // Use _backingController instead of _controller to prevent the lazy getter
+ // from instaniating an AnimationController unnecessarily.
+ switch (_backingController?.status) {
+ case null:
case AnimationStatus.reverse:
case AnimationStatus.dismissed:
break;
@@ -743,7 +743,7 @@
};
final TooltipThemeData tooltipTheme = _tooltipTheme;
- return _TooltipOverlay(
+ final _TooltipOverlay overlayChild = _TooltipOverlay(
richMessage: widget.richMessage ?? TextSpan(text: widget.message),
height: widget.height ?? tooltipTheme.height ?? _getDefaultTooltipHeight(),
padding: widget.padding ?? tooltipTheme.padding ?? _getDefaultPadding(),
@@ -753,21 +753,28 @@
decoration: widget.decoration ?? tooltipTheme.decoration ?? defaultDecoration,
textStyle: widget.textStyle ?? tooltipTheme.textStyle ?? defaultTextStyle,
textAlign: widget.textAlign ?? tooltipTheme.textAlign ?? _defaultTextAlign,
- animation: CurvedAnimation(
- parent: _controller,
- curve: Curves.fastOutSlowIn,
- ),
+ animation: CurvedAnimation(parent: _controller, curve: Curves.fastOutSlowIn),
target: target,
verticalOffset: widget.verticalOffset ?? tooltipTheme.verticalOffset ?? _defaultVerticalOffset,
preferBelow: widget.preferBelow ?? tooltipTheme.preferBelow ?? _defaultPreferBelow,
);
+
+ return SelectionContainer.maybeOf(context) == null
+ ? overlayChild
+ : SelectionContainer.disabled(child: overlayChild);
}
@override
void dispose() {
GestureBinding.instance.pointerRouter.removeGlobalRoute(_handleGlobalPointerEvent);
Tooltip._openedTooltips.remove(this);
+ // _longPressRecognizer.dispose() and _tapRecognizer.dispose() may call
+ // their registered onCancel callbacks if there's a gesture in progress.
+ // Remove the onCancel callbacks to prevent the registered callbacks from
+ // triggering unnecessary side effects (such as animations).
+ _longPressRecognizer?.onLongPressCancel = null;
_longPressRecognizer?.dispose();
+ _tapRecognizer?.onTapCancel = null;
_tapRecognizer?.dispose();
_timer?.cancel();
_backingController?.dispose();
diff --git a/packages/flutter/lib/src/painting/_network_image_io.dart b/packages/flutter/lib/src/painting/_network_image_io.dart
index 827c781..8105227 100644
--- a/packages/flutter/lib/src/painting/_network_image_io.dart
+++ b/packages/flutter/lib/src/painting/_network_image_io.dart
@@ -99,14 +99,14 @@
static final HttpClient _sharedHttpClient = HttpClient()..autoUncompress = false;
static HttpClient get _httpClient {
- HttpClient client = _sharedHttpClient;
+ HttpClient? client;
assert(() {
if (debugNetworkImageHttpClientProvider != null) {
client = debugNetworkImageHttpClientProvider!();
}
return true;
}());
- return client;
+ return client ?? _sharedHttpClient;
}
Future<ui.Codec> _loadAsync(
diff --git a/packages/flutter/lib/src/painting/borders.dart b/packages/flutter/lib/src/painting/borders.dart
index b96713c..82282a6 100644
--- a/packages/flutter/lib/src/painting/borders.dart
+++ b/packages/flutter/lib/src/painting/borders.dart
@@ -840,7 +840,7 @@
}
@override
- bool get preferPaintInterior => true;
+ bool get preferPaintInterior => borders.every((ShapeBorder border) => border.preferPaintInterior);
@override
void paint(Canvas canvas, Rect rect, { TextDirection? textDirection }) {
diff --git a/packages/flutter/lib/src/painting/box_decoration.dart b/packages/flutter/lib/src/painting/box_decoration.dart
index 8385edf..444eb40 100644
--- a/packages/flutter/lib/src/painting/box_decoration.dart
+++ b/packages/flutter/lib/src/painting/box_decoration.dart
@@ -68,6 +68,8 @@
///
/// * [DecoratedBox] and [Container], widgets that can be configured with
/// [BoxDecoration] objects.
+/// * [DecoratedSliver], a widget that can be configured with a [BoxDecoration]
+/// that is converted to render with slivers.
/// * [CustomPaint], a widget that lets you draw arbitrary graphics.
/// * [Decoration], the base class which lets you define other decorations.
class BoxDecoration extends Decoration {
diff --git a/packages/flutter/lib/src/painting/geometry.dart b/packages/flutter/lib/src/painting/geometry.dart
index a5f1487..e57d3cf 100644
--- a/packages/flutter/lib/src/painting/geometry.dart
+++ b/packages/flutter/lib/src/painting/geometry.dart
@@ -48,7 +48,7 @@
// VERTICAL DIRECTION
final bool fitsBelow = target.dy + verticalOffset + childSize.height <= size.height - margin;
final bool fitsAbove = target.dy - verticalOffset - childSize.height >= margin;
- final bool tooltipBelow = preferBelow ? fitsBelow || !fitsAbove : !(fitsAbove || !fitsBelow);
+ final bool tooltipBelow = fitsAbove == fitsBelow ? preferBelow : fitsBelow;
final double y;
if (tooltipBelow) {
y = math.min(target.dy + verticalOffset, size.height - margin);
@@ -56,19 +56,11 @@
y = math.max(target.dy - verticalOffset - childSize.height, margin);
}
// HORIZONTAL DIRECTION
- final double x;
- if (size.width - margin * 2.0 < childSize.width) {
- x = (size.width - childSize.width) / 2.0;
- } else {
- final double normalizedTargetX = clampDouble(target.dx, margin, size.width - margin);
- final double edge = margin + childSize.width / 2.0;
- if (normalizedTargetX < edge) {
- x = margin;
- } else if (normalizedTargetX > size.width - edge) {
- x = size.width - margin - childSize.width;
- } else {
- x = normalizedTargetX - childSize.width / 2.0;
- }
- }
+ final double flexibleSpace = size.width - childSize.width;
+ final double x = flexibleSpace <= 2 * margin
+ // If there's not enough horizontal space for margin + child, center the
+ // child.
+ ? flexibleSpace / 2.0
+ : clampDouble(target.dx - childSize.width / 2, margin, flexibleSpace - margin);
return Offset(x, y);
}
diff --git a/packages/flutter/lib/src/painting/linear_border.dart b/packages/flutter/lib/src/painting/linear_border.dart
index 76dc670..eaa51ee 100644
--- a/packages/flutter/lib/src/painting/linear_border.dart
+++ b/packages/flutter/lib/src/painting/linear_border.dart
@@ -132,6 +132,12 @@
///
/// Convenience constructors are included for the common case where just one edge is specified:
/// [LinearBorder.start], [LinearBorder.end], [LinearBorder.top], [LinearBorder.bottom].
+///
+/// {@tool dartpad}
+/// This example shows how to draw different kinds of [LinearBorder]s.
+///
+/// ** See code in examples/api/lib/painting/linear_border/linear_border.0.dart **
+/// {@end-tool}
class LinearBorder extends OutlinedBorder {
/// Creates a rectangular box border that's rendered as zero to four lines.
const LinearBorder({
diff --git a/packages/flutter/lib/src/painting/shape_decoration.dart b/packages/flutter/lib/src/painting/shape_decoration.dart
index 9909128..20785bc 100644
--- a/packages/flutter/lib/src/painting/shape_decoration.dart
+++ b/packages/flutter/lib/src/painting/shape_decoration.dart
@@ -237,7 +237,7 @@
return ShapeDecoration(
color: Color.lerp(a?.color, b?.color, t),
gradient: Gradient.lerp(a?.gradient, b?.gradient, t),
- image: t < 0.5 ? a!.image : b!.image, // TODO(ianh): cross-fade the image
+ image: t < 0.5 ? a?.image : b?.image, // TODO(ianh): cross-fade the image
shadows: BoxShadow.lerpList(a?.shadows, b?.shadows, t),
shape: ShapeBorder.lerp(a?.shape, b?.shape, t)!,
);
diff --git a/packages/flutter/lib/src/rendering/binding.dart b/packages/flutter/lib/src/rendering/binding.dart
index dec407b..a90e062 100644
--- a/packages/flutter/lib/src/rendering/binding.dart
+++ b/packages/flutter/lib/src/rendering/binding.dart
@@ -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 'dart:developer';
import 'dart:ui' as ui show SemanticsUpdate;
import 'package:flutter/foundation.dart';
@@ -507,13 +506,13 @@
await super.performReassemble();
if (BindingBase.debugReassembleConfig?.widgetName == null) {
if (!kReleaseMode) {
- Timeline.startSync('Preparing Hot Reload (layout)');
+ FlutterTimeline.startSync('Preparing Hot Reload (layout)');
}
try {
renderView.reassemble();
} finally {
if (!kReleaseMode) {
- Timeline.finishSync();
+ FlutterTimeline.finishSync();
}
}
}
diff --git a/packages/flutter/lib/src/rendering/box.dart b/packages/flutter/lib/src/rendering/box.dart
index 6d9b490..3a567e8 100644
--- a/packages/flutter/lib/src/rendering/box.dart
+++ b/packages/flutter/lib/src/rendering/box.dart
@@ -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 'dart:developer' show Timeline;
import 'dart:math' as math;
import 'dart:ui' as ui show lerpDouble;
@@ -1396,7 +1395,7 @@
}());
if (!kReleaseMode) {
if (debugProfileLayoutsEnabled || _debugIntrinsicsDepth == 0) {
- Timeline.startSync(
+ FlutterTimeline.startSync(
'$runtimeType intrinsics',
arguments: debugTimelineArguments,
);
@@ -1411,7 +1410,7 @@
if (!kReleaseMode) {
_debugIntrinsicsDepth -= 1;
if (debugProfileLayoutsEnabled || _debugIntrinsicsDepth == 0) {
- Timeline.finishSync();
+ FlutterTimeline.finishSync();
}
}
return result;
@@ -1832,7 +1831,7 @@
}());
if (!kReleaseMode) {
if (debugProfileLayoutsEnabled || _debugIntrinsicsDepth == 0) {
- Timeline.startSync(
+ FlutterTimeline.startSync(
'$runtimeType.getDryLayout',
arguments: debugTimelineArguments,
);
@@ -1844,7 +1843,7 @@
if (!kReleaseMode) {
_debugIntrinsicsDepth -= 1;
if (debugProfileLayoutsEnabled || _debugIntrinsicsDepth == 0) {
- Timeline.finishSync();
+ FlutterTimeline.finishSync();
}
}
return result;
@@ -2145,7 +2144,6 @@
assert(!_debugDoingBaseline, 'Please see the documentation for computeDistanceToActualBaseline for the required calling conventions of this method.');
assert(!debugNeedsLayout);
assert(() {
- final RenderObject? parent = this.parent as RenderObject?;
if (owner!.debugDoingLayout) {
return (RenderObject.debugActiveLayout == parent) && parent!.debugDoingThisLayout;
}
@@ -2153,7 +2151,6 @@
return ((RenderObject.debugActivePaint == parent) && parent!.debugDoingThisPaint) ||
((RenderObject.debugActivePaint == this) && debugDoingThisPaint);
}
- assert(parent == this.parent);
return false;
}());
assert(_debugSetDoingBaseline(true));
diff --git a/packages/flutter/lib/src/rendering/decorated_sliver.dart b/packages/flutter/lib/src/rendering/decorated_sliver.dart
new file mode 100644
index 0000000..68a85f7
--- /dev/null
+++ b/packages/flutter/lib/src/rendering/decorated_sliver.dart
@@ -0,0 +1,124 @@
+// Copyright 2014 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'object.dart';
+import 'proxy_box.dart';
+import 'proxy_sliver.dart';
+import 'sliver.dart';
+
+/// Paints a [Decoration] either before or after its child paints.
+///
+/// If the child has infinite scroll extent, then the [Decoration] paints itself up to the
+/// bottom cache extent.
+class RenderDecoratedSliver extends RenderProxySliver {
+ /// Creates a decorated sliver.
+ ///
+ /// The [decoration], [position], and [configuration] arguments must not be
+ /// null. By default the decoration paints behind the child.
+ ///
+ /// The [ImageConfiguration] will be passed to the decoration (with the size
+ /// filled in) to let it resolve images.
+ RenderDecoratedSliver({
+ required Decoration decoration,
+ DecorationPosition position = DecorationPosition.background,
+ ImageConfiguration configuration = ImageConfiguration.empty,
+ }) : _decoration = decoration,
+ _position = position,
+ _configuration = configuration;
+
+ /// What decoration to paint.
+ ///
+ /// Commonly a [BoxDecoration].
+ Decoration get decoration => _decoration;
+ Decoration _decoration;
+ set decoration(Decoration value) {
+ if (value == decoration) {
+ return;
+ }
+ _decoration = value;
+ _painter?.dispose();
+ _painter = decoration.createBoxPainter(markNeedsPaint);
+ markNeedsPaint();
+ }
+
+ /// Whether to paint the box decoration behind or in front of the child.
+ DecorationPosition get position => _position;
+ DecorationPosition _position;
+ set position(DecorationPosition value) {
+ if (value == position) {
+ return;
+ }
+ _position = value;
+ markNeedsPaint();
+ }
+
+ /// The settings to pass to the decoration when painting, so that it can
+ /// resolve images appropriately. See [ImageProvider.resolve] and
+ /// [BoxPainter.paint].
+ ///
+ /// The [ImageConfiguration.textDirection] field is also used by
+ /// direction-sensitive [Decoration]s for painting and hit-testing.
+ ImageConfiguration get configuration => _configuration;
+ ImageConfiguration _configuration;
+ set configuration(ImageConfiguration value) {
+ if (value == configuration) {
+ return;
+ }
+ _configuration = value;
+ markNeedsPaint();
+ }
+
+ BoxPainter? _painter;
+
+ @override
+ void attach(covariant PipelineOwner owner) {
+ _painter = decoration.createBoxPainter(markNeedsPaint);
+ super.attach(owner);
+ }
+
+ @override
+ void detach() {
+ _painter?.dispose();
+ _painter = null;
+ super.detach();
+ }
+
+ @override
+ void dispose() {
+ _painter?.dispose();
+ _painter = null;
+ super.dispose();
+ }
+
+ @override
+ void paint(PaintingContext context, Offset offset) {
+ if (child != null && child!.geometry!.visible) {
+ final SliverPhysicalParentData childParentData = child!.parentData! as SliverPhysicalParentData;
+ final Size childSize;
+ final Offset scrollOffset;
+
+ // In the case where the child sliver has infinite scroll extent, the decoration
+ // should only extend down to the bottom cache extent.
+ final double cappedMainAxisExtent = child!.geometry!.scrollExtent.isInfinite
+ ? constraints.scrollOffset + child!.geometry!.cacheExtent + constraints.cacheOrigin
+ : child!.geometry!.scrollExtent;
+ switch (constraints.axis) {
+ case Axis.vertical:
+ childSize = Size(constraints.crossAxisExtent, cappedMainAxisExtent);
+ scrollOffset = Offset(0.0, -constraints.scrollOffset);
+ case Axis.horizontal:
+ childSize = Size(cappedMainAxisExtent, constraints.crossAxisExtent);
+ scrollOffset = Offset(-constraints.scrollOffset, 0.0);
+ }
+ final Offset childOffset = offset + childParentData.paintOffset;
+ if (position == DecorationPosition.background) {
+ _painter!.paint(context.canvas, childOffset + scrollOffset, configuration.copyWith(size: childSize));
+ }
+ context.paintChild(child!, childOffset);
+ if (position == DecorationPosition.foreground) {
+ _painter!.paint(context.canvas, childOffset + scrollOffset, configuration.copyWith(size: childSize));
+ }
+ }
+ }
+}
diff --git a/packages/flutter/lib/src/rendering/editable.dart b/packages/flutter/lib/src/rendering/editable.dart
index 07853bb..a357bde 100644
--- a/packages/flutter/lib/src/rendering/editable.dart
+++ b/packages/flutter/lib/src/rendering/editable.dart
@@ -25,15 +25,10 @@
// The additional size on the x and y axis with which to expand the prototype
// cursor to render the floating cursor in pixels.
-const EdgeInsets _kFloatingCaretSizeIncrease = EdgeInsets.symmetric(horizontal: 0.5, vertical: 1.0);
+const EdgeInsets _kFloatingCursorSizeIncrease = EdgeInsets.symmetric(horizontal: 0.5, vertical: 1.0);
// The corner radius of the floating cursor in pixels.
-const Radius _kFloatingCaretRadius = Radius.circular(1.0);
-
-/// Signature for the callback that reports when the caret location changes.
-///
-/// Used by [RenderEditable.onCaretChanged].
-typedef CaretChangedHandler = void Function(Rect caretRect);
+const Radius _kFloatingCursorRadius = Radius.circular(1.0);
/// Represents the coordinates of the point in a selection, and the text
/// direction at that point, relative to top left of the [RenderEditable] that
@@ -260,9 +255,6 @@
/// position. The cursor is shown while [showCursor] is true. It is painted in
/// the [cursorColor].
///
-/// If, when the render object paints, the caret is found to have changed
-/// location, [onCaretChanged] is called.
-///
/// Keyboard handling, IME handling, scrolling, toggling the [showCursor] value
/// to actually blink the cursor, and other features not mentioned above are the
/// responsibility of higher layers and not handled by this object.
@@ -299,7 +291,6 @@
double textScaleFactor = 1.0,
TextSelection? selection,
required ViewportOffset offset,
- this.onCaretChanged,
this.ignorePointer = false,
bool readOnly = false,
bool forceLine = true,
@@ -474,8 +465,8 @@
}
// Caret Painters:
- // The floating painter. This painter paints the regular caret as well.
- late final _FloatingCursorPainter _caretPainter = _FloatingCursorPainter(_onCaretChanged);
+ // A single painter for both the regular caret and the floating cursor.
+ late final _CaretPainter _caretPainter = _CaretPainter();
// Text Highlight painters:
final _TextHighlightPainter _selectionPainter = _TextHighlightPainter();
@@ -515,19 +506,6 @@
);
}
- Rect? _lastCaretRect;
- // TODO(LongCatIsLooong): currently EditableText uses this callback to keep
- // the text field visible. But we don't always paint the caret, for example
- // when the selection is not collapsed.
- /// Called during the paint phase when the caret location changes.
- CaretChangedHandler? onCaretChanged;
- void _onCaretChanged(Rect caretRect) {
- if (_lastCaretRect != caretRect) {
- onCaretChanged?.call(caretRect);
- }
- _lastCaretRect = onCaretChanged == null ? null : caretRect;
- }
-
/// Whether the [handleEvent] will propagate pointer events to selection
/// handlers.
///
@@ -2067,9 +2045,9 @@
void selectWordsInRange({ required Offset from, Offset? to, required SelectionChangedCause cause }) {
_computeTextMetricsIfNeeded();
final TextPosition fromPosition = _textPainter.getPositionForOffset(globalToLocal(from - _paintOffset));
- final TextSelection fromWord = _getWordAtOffset(fromPosition);
+ final TextSelection fromWord = getWordAtOffset(fromPosition);
final TextPosition toPosition = to == null ? fromPosition : _textPainter.getPositionForOffset(globalToLocal(to - _paintOffset));
- final TextSelection toWord = toPosition == fromPosition ? fromWord : _getWordAtOffset(toPosition);
+ final TextSelection toWord = toPosition == fromPosition ? fromWord : getWordAtOffset(toPosition);
final bool isFromWordBeforeToWord = fromWord.start < toWord.end;
_setSelection(
@@ -2099,7 +2077,10 @@
_setSelection(newSelection, cause);
}
- TextSelection _getWordAtOffset(TextPosition position) {
+ /// Returns a [TextSelection] that encompasses the word at the given
+ /// [TextPosition].
+ @visibleForTesting
+ TextSelection getWordAtOffset(TextPosition position) {
debugAssertLayoutUpToDate();
// When long-pressing past the end of the text, we want a collapsed cursor.
if (position.offset >= plainText.length) {
@@ -2120,6 +2101,7 @@
case TextAffinity.downstream:
effectiveOffset = position.offset;
}
+ assert(effectiveOffset >= 0);
// On iOS, select the previous word if there is a previous word, or select
// to the end of the next word if there is a next word. Select nothing if
@@ -2128,8 +2110,8 @@
// If the platform is Android and the text is read only, try to select the
// previous word if there is one; otherwise, select the single whitespace at
// the position.
- if (TextLayoutMetrics.isWhitespace(plainText.codeUnitAt(effectiveOffset))
- && effectiveOffset > 0) {
+ if (effectiveOffset > 0
+ && TextLayoutMetrics.isWhitespace(plainText.codeUnitAt(effectiveOffset))) {
final TextRange? previousWord = _getPreviousWord(word.start);
switch (defaultTargetPlatform) {
case TargetPlatform.iOS:
@@ -2392,8 +2374,8 @@
_floatingCursorTextPosition = lastTextPosition;
final double? animationValue = _resetFloatingCursorAnimationValue;
final EdgeInsets sizeAdjustment = animationValue != null
- ? EdgeInsets.lerp(_kFloatingCaretSizeIncrease, EdgeInsets.zero, animationValue)!
- : _kFloatingCaretSizeIncrease;
+ ? EdgeInsets.lerp(_kFloatingCursorSizeIncrease, EdgeInsets.zero, animationValue)!
+ : _kFloatingCursorSizeIncrease;
_caretPainter.floatingCursorRect = sizeAdjustment.inflateRect(_caretPrototype).shift(boundedOffset);
} else {
_caretPainter.floatingCursorRect = null;
@@ -2773,8 +2755,8 @@
}
}
-class _FloatingCursorPainter extends RenderEditablePainter {
- _FloatingCursorPainter(this.caretPaintCallback);
+class _CaretPainter extends RenderEditablePainter {
+ _CaretPainter();
bool get shouldPaint => _shouldPaint;
bool _shouldPaint = true;
@@ -2786,8 +2768,6 @@
notifyListeners();
}
- CaretChangedHandler caretPaintCallback;
-
bool showRegularCaret = false;
final Paint caretPaint = Paint();
@@ -2859,7 +2839,6 @@
canvas.drawRRect(caretRRect, caretPaint);
}
}
- caretPaintCallback(integralRect);
}
@override
@@ -2893,7 +2872,7 @@
}
canvas.drawRRect(
- RRect.fromRectAndRadius(floatingCursorRect, _kFloatingCaretRadius),
+ RRect.fromRectAndRadius(floatingCursorRect, _kFloatingCursorRadius),
floatingCursorPaint..color = floatingCursorColor,
);
}
@@ -2907,7 +2886,7 @@
if (oldDelegate == null) {
return shouldPaint;
}
- return oldDelegate is! _FloatingCursorPainter
+ return oldDelegate is! _CaretPainter
|| oldDelegate.shouldPaint != shouldPaint
|| oldDelegate.showRegularCaret != showRegularCaret
|| oldDelegate.caretColor != caretColor
diff --git a/packages/flutter/lib/src/rendering/list_wheel_viewport.dart b/packages/flutter/lib/src/rendering/list_wheel_viewport.dart
index 8296910..48bc762 100644
--- a/packages/flutter/lib/src/rendering/list_wheel_viewport.dart
+++ b/packages/flutter/lib/src/rendering/list_wheel_viewport.dart
@@ -1133,7 +1133,7 @@
// `child` will be the last RenderObject before the viewport when walking up from `target`.
RenderObject child = target;
while (child.parent != this) {
- child = child.parent! as RenderObject;
+ child = child.parent!;
}
final ListWheelParentData parentData = child.parentData! as ListWheelParentData;
diff --git a/packages/flutter/lib/src/rendering/object.dart b/packages/flutter/lib/src/rendering/object.dart
index 0beedd7..3e42a22 100644
--- a/packages/flutter/lib/src/rendering/object.dart
+++ b/packages/flutter/lib/src/rendering/object.dart
@@ -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 'dart:developer';
import 'dart:ui' as ui show PictureRecorder;
import 'dart:ui';
@@ -929,11 +928,9 @@
}
/// The unique object managed by this pipeline that has no parent.
- ///
- /// This object does not have to be a [RenderObject].
- AbstractNode? get rootNode => _rootNode;
- AbstractNode? _rootNode;
- set rootNode(AbstractNode? value) {
+ RenderObject? get rootNode => _rootNode;
+ RenderObject? _rootNode;
+ set rootNode(RenderObject? value) {
if (_rootNode == value) {
return;
}
@@ -988,7 +985,7 @@
}
return true;
}());
- Timeline.startSync(
+ FlutterTimeline.startSync(
'LAYOUT',
arguments: debugTimelineArguments,
);
@@ -1037,7 +1034,7 @@
return true;
}());
if (!kReleaseMode) {
- Timeline.finishSync();
+ FlutterTimeline.finishSync();
}
}
}
@@ -1076,7 +1073,7 @@
/// [flushPaint].
void flushCompositingBits() {
if (!kReleaseMode) {
- Timeline.startSync('UPDATING COMPOSITING BITS');
+ FlutterTimeline.startSync('UPDATING COMPOSITING BITS');
}
_nodesNeedingCompositingBitsUpdate.sort((RenderObject a, RenderObject b) => a.depth - b.depth);
for (final RenderObject node in _nodesNeedingCompositingBitsUpdate) {
@@ -1090,7 +1087,7 @@
}
assert(_nodesNeedingCompositingBitsUpdate.isEmpty, 'Child PipelineOwners must not dirty nodes in their parent.');
if (!kReleaseMode) {
- Timeline.finishSync();
+ FlutterTimeline.finishSync();
}
}
@@ -1124,7 +1121,7 @@
}
return true;
}());
- Timeline.startSync(
+ FlutterTimeline.startSync(
'PAINT',
arguments: debugTimelineArguments,
);
@@ -1163,7 +1160,7 @@
return true;
}());
if (!kReleaseMode) {
- Timeline.finishSync();
+ FlutterTimeline.finishSync();
}
}
}
@@ -1252,7 +1249,7 @@
return;
}
if (!kReleaseMode) {
- Timeline.startSync('SEMANTICS');
+ FlutterTimeline.startSync('SEMANTICS');
}
assert(_semanticsOwner != null);
assert(() {
@@ -1279,7 +1276,7 @@
return true;
}());
if (!kReleaseMode) {
- Timeline.finishSync();
+ FlutterTimeline.finishSync();
}
}
}
@@ -1572,7 +1569,7 @@
/// [RenderObject.markNeedsLayout] so that if a parent has queried the intrinsic
/// or baseline information, it gets marked dirty whenever the child's geometry
/// changes.
-abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin implements HitTestTarget {
+abstract class RenderObject with DiagnosticableTreeMixin implements HitTestTarget {
/// Initializes internal fields for subclasses.
RenderObject() {
if (kFlutterMemoryAllocationsEnabled) {
@@ -1690,30 +1687,93 @@
}
}
+ /// The depth of this node in the tree.
+ ///
+ /// The depth of nodes in a tree monotonically increases as you traverse down
+ /// the tree.
+ ///
+ /// Nodes always have a [depth] greater than their ancestors'. There's no
+ /// guarantee regarding depth between siblings. The depth of a node is used to
+ /// ensure that nodes are processed in depth order. The [depth] of a child can
+ /// be more than one greater than the [depth] of the parent, because the [depth]
+ /// values are never decreased: all that matters is that it's greater than the
+ /// parent. Consider a tree with a root node A, a child B, and a grandchild C.
+ /// Initially, A will have [depth] 0, B [depth] 1, and C [depth] 2. If C is
+ /// moved to be a child of A, sibling of B, then the numbers won't change. C's
+ /// [depth] will still be 2. The [depth] is automatically maintained by the
+ /// [adoptChild] and [dropChild] methods.
+ int get depth => _depth;
+ int _depth = 0;
+
+ /// Adjust the [depth] of the given [child] to be greater than this node's own
+ /// [depth].
+ ///
+ /// Only call this method from overrides of [redepthChildren].
+ @protected
+ void redepthChild(RenderObject child) {
+ assert(child.owner == owner);
+ if (child._depth <= _depth) {
+ child._depth = _depth + 1;
+ child.redepthChildren();
+ }
+ }
+
+ /// Adjust the [depth] of this node's children, if any.
+ ///
+ /// Override this method in subclasses with child nodes to call [redepthChild]
+ /// for each child. Do not call this method directly.
+ @protected
+ void redepthChildren() { }
+
+ /// The parent of this node in the tree.
+ RenderObject? get parent => _parent;
+ RenderObject? _parent;
+
/// Called by subclasses when they decide a render object is a child.
///
/// Only for use by subclasses when changing their child lists. Calling this
/// in other cases will lead to an inconsistent tree and probably cause crashes.
- @override
+ @mustCallSuper
+ @protected
void adoptChild(RenderObject child) {
+ assert(child._parent == null);
+ assert(() {
+ RenderObject node = this;
+ while (node.parent != null) {
+ node = node.parent!;
+ }
+ assert(node != child); // indicates we are about to create a cycle
+ return true;
+ }());
+
setupParentData(child);
markNeedsLayout();
markNeedsCompositingBitsUpdate();
markNeedsSemanticsUpdate();
- super.adoptChild(child);
+ child._parent = this;
+ if (attached) {
+ child.attach(_owner!);
+ }
+ redepthChild(child);
}
/// Called by subclasses when they decide a render object is no longer a child.
///
/// Only for use by subclasses when changing their child lists. Calling this
/// in other cases will lead to an inconsistent tree and probably cause crashes.
- @override
+ @mustCallSuper
+ @protected
void dropChild(RenderObject child) {
+ assert(child._parent == this);
+ assert(child.attached == attached);
assert(child.parentData != null);
child._cleanRelayoutBoundary();
child.parentData!.detach();
child.parentData = null;
- super.dropChild(child);
+ child._parent = null;
+ if (attached) {
+ child.detach();
+ }
markNeedsLayout();
markNeedsCompositingBitsUpdate();
markNeedsSemanticsUpdate();
@@ -1851,7 +1911,7 @@
}
if (!activeLayoutRoot._debugMutationsLocked) {
- final AbstractNode? p = activeLayoutRoot.debugLayoutParent;
+ final RenderObject? p = activeLayoutRoot.debugLayoutParent;
activeLayoutRoot = p is RenderObject ? p : null;
} else {
// activeLayoutRoot found.
@@ -1946,20 +2006,41 @@
RenderObject? get debugLayoutParent {
RenderObject? layoutParent;
assert(() {
- final AbstractNode? parent = this.parent;
- layoutParent = parent is RenderObject? ? parent : null;
+ layoutParent = parent;
return true;
}());
return layoutParent;
}
- @override
- PipelineOwner? get owner => super.owner as PipelineOwner?;
+ /// The owner for this node (null if unattached).
+ ///
+ /// The entire subtree that this node belongs to will have the same owner.
+ PipelineOwner? get owner => _owner;
+ PipelineOwner? _owner;
- @override
+ /// Whether this node is in a tree whose root is attached to something.
+ ///
+ /// This becomes true during the call to [attach].
+ ///
+ /// This becomes false during the call to [detach].
+ bool get attached => _owner != null;
+
+ /// Mark this node as attached to the given owner.
+ ///
+ /// Typically called only from the [parent]'s [attach] method, and by the
+ /// [owner] to mark the root of a tree as attached.
+ ///
+ /// Subclasses with children should override this method to first call their
+ /// inherited [attach] method, and then [attach] all their children to the
+ /// same [owner].
+ ///
+ /// Implementations of this method should start with a call to the inherited
+ /// method, as in `super.attach(owner)`.
+ @mustCallSuper
void attach(PipelineOwner owner) {
assert(!_debugDisposed);
- super.attach(owner);
+ assert(_owner == null);
+ _owner = owner;
// If the node was dirtied in some way while unattached, make sure to add
// it to the appropriate dirty list now that an owner is available
if (_needsLayout && _relayoutBoundary != null) {
@@ -1986,6 +2067,23 @@
}
}
+ /// Mark this node as detached.
+ ///
+ /// Typically called only from the [parent]'s [detach], and by the [owner] to
+ /// mark the root of a tree as detached.
+ ///
+ /// Subclasses with children should override this method to first call their
+ /// inherited [detach] method, and then [detach] all their children.
+ ///
+ /// Implementations of this method should end with a call to the inherited
+ /// method, as in `super.detach()`.
+ @mustCallSuper
+ void detach() {
+ assert(_owner != null);
+ _owner = null;
+ assert(parent == null || attached == parent!.attached);
+ }
+
/// Whether this render object's layout information is dirty.
///
/// This is only set in debug mode. In general, render objects should not need
@@ -2050,7 +2148,7 @@
while (node != _relayoutBoundary) {
assert(node._relayoutBoundary == _relayoutBoundary);
assert(node.parent != null);
- node = node.parent! as RenderObject;
+ node = node.parent!;
if ((!node._needsLayout) && (!node._debugDoingThisLayout)) {
return false;
}
@@ -2144,7 +2242,7 @@
assert(_debugCanPerformMutations);
_needsLayout = true;
assert(this.parent != null);
- final RenderObject parent = this.parent! as RenderObject;
+ final RenderObject parent = this.parent!;
if (!_doingThisLayoutWithCallback) {
parent.markNeedsLayout();
} else {
@@ -2176,7 +2274,7 @@
if (_relayoutBoundary == this) {
return;
}
- final RenderObject? parentRelayoutBoundary = (parent as RenderObject?)?._relayoutBoundary;
+ final RenderObject? parentRelayoutBoundary = parent?._relayoutBoundary;
assert(parentRelayoutBoundary != null);
if (parentRelayoutBoundary != _relayoutBoundary) {
_relayoutBoundary = parentRelayoutBoundary;
@@ -2280,7 +2378,7 @@
}
return true;
}());
- Timeline.startSync(
+ FlutterTimeline.startSync(
'$runtimeType',
arguments: debugTimelineArguments,
);
@@ -2290,10 +2388,11 @@
informationCollector: () {
final List<String> stack = StackTrace.current.toString().split('\n');
int? targetFrame;
- final Pattern layoutFramePattern = RegExp(r'^#[0-9]+ +RenderObject.layout \(');
+ final Pattern layoutFramePattern = RegExp(r'^#[0-9]+ +Render(?:Object|Box).layout \(');
for (int i = 0; i < stack.length; i += 1) {
if (layoutFramePattern.matchAsPrefix(stack[i]) != null) {
targetFrame = i + 1;
+ } else if (targetFrame != null) {
break;
}
}
@@ -2301,7 +2400,6 @@
final Pattern targetFramePattern = RegExp(r'^#[0-9]+ +(.+)$');
final Match? targetFrameMatch = targetFramePattern.matchAsPrefix(stack[targetFrame]);
final String? problemFunction = (targetFrameMatch != null && targetFrameMatch.groupCount > 0) ? targetFrameMatch.group(1) : stack[targetFrame].trim();
- // TODO(jacobr): this case is similar to displaying a single stack frame.
return <DiagnosticsNode>[
ErrorDescription(
"These invalid constraints were provided to $runtimeType's layout() "
@@ -2317,7 +2415,7 @@
assert(!_debugDoingThisResize);
assert(!_debugDoingThisLayout);
final bool isRelayoutBoundary = !parentUsesSize || sizedByParent || constraints.isTight || parent is! RenderObject;
- final RenderObject relayoutBoundary = isRelayoutBoundary ? this : (parent! as RenderObject)._relayoutBoundary!;
+ final RenderObject relayoutBoundary = isRelayoutBoundary ? this : parent!._relayoutBoundary!;
assert(() {
_debugCanParentUseSize = parentUsesSize;
return true;
@@ -2344,7 +2442,7 @@
}
if (!kReleaseMode && debugProfileLayoutsEnabled) {
- Timeline.finishSync();
+ FlutterTimeline.finishSync();
}
return;
}
@@ -2411,7 +2509,7 @@
markNeedsPaint();
if (!kReleaseMode && debugProfileLayoutsEnabled) {
- Timeline.finishSync();
+ FlutterTimeline.finishSync();
}
}
@@ -2674,7 +2772,7 @@
}
_needsCompositingBitsUpdate = true;
if (parent is RenderObject) {
- final RenderObject parent = this.parent! as RenderObject;
+ final RenderObject parent = this.parent!;
if (parent._needsCompositingBitsUpdate) {
return;
}
@@ -2823,9 +2921,7 @@
owner!.requestVisualUpdate();
}
} else if (parent is RenderObject) {
- final RenderObject parent = this.parent! as RenderObject;
- parent.markNeedsPaint();
- assert(parent == this.parent);
+ parent!.markNeedsPaint();
} else {
assert(() {
if (debugPrintMarkNeedsPaintStacks) {
@@ -2896,7 +2992,7 @@
assert(_needsPaint || _needsCompositedLayerUpdate);
assert(_layerHandle.layer != null);
assert(!_layerHandle.layer!.attached);
- AbstractNode? node = parent;
+ RenderObject? node = parent;
while (node is RenderObject) {
if (node.isRepaintBoundary) {
if (node._layerHandle.layer == null) {
@@ -2985,7 +3081,7 @@
}
return true;
}());
- Timeline.startSync(
+ FlutterTimeline.startSync(
'$runtimeType',
arguments: debugTimelineArguments,
);
@@ -2993,7 +3089,7 @@
assert(() {
if (_needsCompositingBitsUpdate) {
if (parent is RenderObject) {
- final RenderObject parent = this.parent! as RenderObject;
+ final RenderObject parent = this.parent!;
bool visitedByParent = false;
parent.visitChildren((RenderObject child) {
if (child == this) {
@@ -3069,7 +3165,7 @@
return true;
}());
if (!kReleaseMode && debugProfilePaintsEnabled) {
- Timeline.finishSync();
+ FlutterTimeline.finishSync();
}
}
@@ -3156,13 +3252,13 @@
final bool ancestorSpecified = ancestor != null;
assert(attached);
if (ancestor == null) {
- final AbstractNode? rootNode = owner!.rootNode;
+ final RenderObject? rootNode = owner!.rootNode;
if (rootNode is RenderObject) {
ancestor = rootNode;
}
}
final List<RenderObject> renderers = <RenderObject>[];
- for (RenderObject renderer = this; renderer != ancestor; renderer = renderer.parent! as RenderObject) {
+ for (RenderObject renderer = this; renderer != ancestor; renderer = renderer.parent!) {
renderers.add(renderer);
assert(renderer.parent != null); // Failed to find ancestor in parent chain.
}
@@ -3294,8 +3390,7 @@
if (_semantics != null && !_semantics!.isMergedIntoParent) {
_semantics!.sendEvent(semanticsEvent);
} else if (parent != null) {
- final RenderObject renderParent = parent! as RenderObject;
- renderParent.sendSemanticsEvent(semanticsEvent);
+ parent!.sendSemanticsEvent(semanticsEvent);
}
}
@@ -3395,7 +3490,7 @@
mayProduceSiblingNodes = false;
}
- node = node.parent! as RenderObject;
+ node = node.parent!;
isEffectiveSemanticsBoundary = node._semanticsConfiguration.isSemanticBoundary;
if (isEffectiveSemanticsBoundary && node._semantics == null) {
// We have reached a semantics boundary that doesn't own a semantics node.
@@ -3432,14 +3527,24 @@
// The subtree is probably being kept alive by a viewport but not laid out.
return;
}
+ if (!kReleaseMode) {
+ FlutterTimeline.startSync('Semantics.GetFragment');
+ }
final _SemanticsFragment fragment = _getSemanticsForParent(
mergeIntoParent: _semantics?.parent?.isPartOfNodeMerging ?? false,
blockUserActions: _semantics?.areUserActionsBlocked ?? false,
);
+ if (!kReleaseMode) {
+ FlutterTimeline.finishSync();
+ }
assert(fragment is _InterestingSemanticsFragment);
final _InterestingSemanticsFragment interestingFragment = fragment as _InterestingSemanticsFragment;
final List<SemanticsNode> result = <SemanticsNode>[];
final List<SemanticsNode> siblingNodes = <SemanticsNode>[];
+
+ if (!kReleaseMode) {
+ FlutterTimeline.startSync('Semantics.compileChildren');
+ }
interestingFragment.compileChildren(
parentSemanticsClipRect: _semantics?.parentSemanticsClipRect,
parentPaintClipRect: _semantics?.parentPaintClipRect,
@@ -3447,6 +3552,9 @@
result: result,
siblingNodes: siblingNodes,
);
+ if (!kReleaseMode) {
+ FlutterTimeline.finishSync();
+ }
// Result may contain sibling nodes that are irrelevant for this update.
assert(interestingFragment.config == null && result.any((SemanticsNode node) => node == _semantics));
}
@@ -3678,9 +3786,9 @@
}
if (_relayoutBoundary != null && _relayoutBoundary != this) {
int count = 1;
- RenderObject? target = parent as RenderObject?;
+ RenderObject? target = parent;
while (target != null && target != _relayoutBoundary) {
- target = target.parent as RenderObject?;
+ target = target.parent;
count += 1;
}
header += ' relayoutBoundary=up$count';
@@ -3782,8 +3890,7 @@
Curve curve = Curves.ease,
}) {
if (parent is RenderObject) {
- final RenderObject renderParent = parent! as RenderObject;
- renderParent.showOnScreen(
+ parent!.showOnScreen(
descendant: descendant ?? this,
rect: rect,
duration: duration,
@@ -4970,11 +5077,11 @@
Matrix4 clipRectTransform,
) {
assert(clipRectTransform.isIdentity());
- RenderObject intermediateParent = child.parent! as RenderObject;
+ RenderObject intermediateParent = child.parent!;
while (intermediateParent != ancestor) {
intermediateParent.applyPaintTransform(child, transform);
- intermediateParent = intermediateParent.parent! as RenderObject;
- child = child.parent! as RenderObject;
+ intermediateParent = intermediateParent.parent!;
+ child = child.parent!;
}
ancestor.applyPaintTransform(child, transform);
ancestor.applyPaintTransform(child, clipRectTransform);
diff --git a/packages/flutter/lib/src/rendering/paragraph.dart b/packages/flutter/lib/src/rendering/paragraph.dart
index e9b0402..066f613 100644
--- a/packages/flutter/lib/src/rendering/paragraph.dart
+++ b/packages/flutter/lib/src/rendering/paragraph.dart
@@ -1335,6 +1335,14 @@
: paragraph._getOffsetForPosition(TextPosition(offset: selectionEnd));
final bool flipHandles = isReversed != (TextDirection.rtl == paragraph.textDirection);
final Matrix4 paragraphToFragmentTransform = getTransformToParagraph()..invert();
+ final TextSelection selection = TextSelection(
+ baseOffset: selectionStart,
+ extentOffset: selectionEnd,
+ );
+ final List<Rect> selectionRects = <Rect>[];
+ for (final TextBox textBox in paragraph.getBoxesForSelection(selection)) {
+ selectionRects.add(textBox.toRect());
+ }
return SelectionGeometry(
startSelectionPoint: SelectionPoint(
localPosition: MatrixUtils.transformPoint(paragraphToFragmentTransform, startOffsetInParagraphCoordinates),
@@ -1346,6 +1354,7 @@
lineHeight: paragraph._textPainter.preferredLineHeight,
handleType: flipHandles ? TextSelectionHandleType.left : TextSelectionHandleType.right,
),
+ selectionRects: selectionRects,
status: _textSelectionStart!.offset == _textSelectionEnd!.offset
? SelectionStatus.collapsed
: SelectionStatus.uncollapsed,
@@ -1488,7 +1497,7 @@
assert(word.start >= range.start && word.end <= range.end);
late TextPosition start;
late TextPosition end;
- if (position.offset >= word.end) {
+ if (position.offset > word.end) {
start = end = TextPosition(offset: position.offset);
} else {
start = TextPosition(offset: word.start);
diff --git a/packages/flutter/lib/src/rendering/selection.dart b/packages/flutter/lib/src/rendering/selection.dart
index 38a47d7..beaf5a0 100644
--- a/packages/flutter/lib/src/rendering/selection.dart
+++ b/packages/flutter/lib/src/rendering/selection.dart
@@ -576,8 +576,8 @@
/// The geometry of the current selection.
///
/// This includes details such as the locations of the selection start and end,
-/// line height, etc. This information is used for drawing selection controls
-/// for mobile platforms.
+/// line height, the rects that encompass the selection, etc. This information
+/// is used for drawing selection controls for mobile platforms.
///
/// The positions in geometry are in local coordinates of the [SelectionHandler]
/// or [Selectable].
@@ -590,6 +590,7 @@
const SelectionGeometry({
this.startSelectionPoint,
this.endSelectionPoint,
+ this.selectionRects = const <Rect>[],
required this.status,
required this.hasContent,
}) : assert((startSelectionPoint == null && endSelectionPoint == null) || status != SelectionStatus.none);
@@ -627,6 +628,10 @@
/// The status of ongoing selection in the [Selectable] or [SelectionHandler].
final SelectionStatus status;
+ /// The rects in the local coordinates of the containing [Selectable] that
+ /// represent the selection if there is any.
+ final List<Rect> selectionRects;
+
/// Whether there is any selectable content in the [Selectable] or
/// [SelectionHandler].
final bool hasContent;
@@ -638,12 +643,14 @@
SelectionGeometry copyWith({
SelectionPoint? startSelectionPoint,
SelectionPoint? endSelectionPoint,
+ List<Rect>? selectionRects,
SelectionStatus? status,
bool? hasContent,
}) {
return SelectionGeometry(
startSelectionPoint: startSelectionPoint ?? this.startSelectionPoint,
endSelectionPoint: endSelectionPoint ?? this.endSelectionPoint,
+ selectionRects: selectionRects ?? this.selectionRects,
status: status ?? this.status,
hasContent: hasContent ?? this.hasContent,
);
@@ -660,6 +667,7 @@
return other is SelectionGeometry
&& other.startSelectionPoint == startSelectionPoint
&& other.endSelectionPoint == endSelectionPoint
+ && other.selectionRects == selectionRects
&& other.status == status
&& other.hasContent == hasContent;
}
@@ -669,6 +677,7 @@
return Object.hash(
startSelectionPoint,
endSelectionPoint,
+ selectionRects,
status,
hasContent,
);
diff --git a/packages/flutter/lib/src/rendering/view.dart b/packages/flutter/lib/src/rendering/view.dart
index ac397ad..906d237 100644
--- a/packages/flutter/lib/src/rendering/view.dart
+++ b/packages/flutter/lib/src/rendering/view.dart
@@ -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 'dart:developer';
import 'dart:io' show Platform;
import 'dart:ui' as ui show FlutterView, Scene, SceneBuilder, SemanticsUpdate;
@@ -229,7 +228,7 @@
/// Actually causes the output of the rendering pipeline to appear on screen.
void compositeFrame() {
if (!kReleaseMode) {
- Timeline.startSync('COMPOSITING');
+ FlutterTimeline.startSync('COMPOSITING');
}
try {
final ui.SceneBuilder builder = ui.SceneBuilder();
@@ -247,7 +246,7 @@
}());
} finally {
if (!kReleaseMode) {
- Timeline.finishSync();
+ FlutterTimeline.finishSync();
}
}
}
diff --git a/packages/flutter/lib/src/rendering/viewport.dart b/packages/flutter/lib/src/rendering/viewport.dart
index bf07a88..44876d8 100644
--- a/packages/flutter/lib/src/rendering/viewport.dart
+++ b/packages/flutter/lib/src/rendering/viewport.dart
@@ -45,7 +45,7 @@
if (object is RenderAbstractViewport) {
return object;
}
- object = object.parent as RenderObject?;
+ object = object.parent;
}
return null;
}
@@ -779,7 +779,7 @@
RenderBox? pivot;
bool onlySlivers = target is RenderSliver; // ... between viewport and `target` (`target` included).
while (child.parent != this) {
- final RenderObject parent = child.parent! as RenderObject;
+ final RenderObject parent = child.parent!;
if (child is RenderBox) {
pivot = child;
}
@@ -1205,7 +1205,8 @@
} else {
// `descendant` is between leading and trailing edge and hence already
// fully shown on screen. No action necessary.
- final Matrix4 transform = descendant.getTransformTo(viewport.parent! as RenderObject);
+ assert(viewport.parent != null);
+ final Matrix4 transform = descendant.getTransformTo(viewport.parent);
return MatrixUtils.transformRect(transform, rect ?? descendant.paintBounds);
}
diff --git a/packages/flutter/lib/src/services/asset_manifest.dart b/packages/flutter/lib/src/services/asset_manifest.dart
index d487e10..3b27490 100644
--- a/packages/flutter/lib/src/services/asset_manifest.dart
+++ b/packages/flutter/lib/src/services/asset_manifest.dart
@@ -15,7 +15,7 @@
const String _kAssetManifestFilename = 'AssetManifest.bin';
/// Contains details about available assets and their variants.
-/// See [Asset variants](https://docs.flutter.dev/development/ui/assets-and-images#asset-variants)
+/// See [Resolution-aware image assets](https://docs.flutter.dev/ui/assets-and-images#resolution-aware)
/// to learn about asset variants and how to declare them.
abstract class AssetManifest {
/// Loads asset manifest data from an [AssetBundle] object and creates an
@@ -31,8 +31,8 @@
/// file at build time.
///
/// See [Specifying assets](https://docs.flutter.dev/development/ui/assets-and-images#specifying-assets)
- /// and [Loading assets](https://docs.flutter.dev/development/ui/assets-and-images#loading-assets) for more
- /// information.
+ /// and [Loading assets](https://docs.flutter.dev/development/ui/assets-and-images#loading-assets)
+ /// for more information.
List<String> listAssets();
/// Retrieves metadata about an asset and its variants. Returns null if the
@@ -119,7 +119,7 @@
/// This will be null if the parent folder name is not a ratio value followed
/// by an "x".
///
- /// See [Declaring resolution-aware image assets](https://docs.flutter.dev/development/ui/assets-and-images#resolution-aware)
+ /// See [Resolution-aware image assets](https://docs.flutter.dev/development/ui/assets-and-images#resolution-aware)
/// for more information.
final double? targetDevicePixelRatio;
@@ -129,8 +129,5 @@
/// Whether or not this is a main asset. In other words, this is true if
/// this asset is not a variant of another asset.
- ///
- /// See [Asset variants](https://docs.flutter.dev/development/ui/assets-and-images#asset-variants)
- /// for more about asset variants.
final bool main;
}
diff --git a/packages/flutter/lib/src/services/dom.dart b/packages/flutter/lib/src/services/dom.dart
index 00d3770..42235a8 100644
--- a/packages/flutter/lib/src/services/dom.dart
+++ b/packages/flutter/lib/src/services/dom.dart
@@ -117,7 +117,7 @@
external JSNumber? get _status;
/// Gets the status.
- int? get status => _status?.toDart.toInt();
+ int? get status => _status?.toDartInt;
@JS('responseType')
external set _responseType(JSString value);
@@ -184,13 +184,13 @@
external JSNumber? get _loaded;
/// Amount of work done.
- int? get loaded => _loaded?.toDart.toInt();
+ int? get loaded => _loaded?.toDartInt;
@JS('total')
external JSNumber? get _total;
/// Total amount of work.
- int? get total => _total?.toDart.toInt();
+ int? get total => _total?.toDartInt;
}
/// The underlying DOM document.
@@ -291,19 +291,19 @@
external JSNumber get _offsetX;
/// Returns the current x offset.
- num get offsetX => _offsetX.toDart;
+ num get offsetX => _offsetX.toDartDouble;
@JS('offsetY')
external JSNumber get _offsetY;
/// Returns the current y offset.
- num get offsetY => _offsetY.toDart;
+ num get offsetY => _offsetY.toDartDouble;
@JS('button')
external JSNumber get _button;
/// Returns the current button.
- int get button => _button.toDart.toInt();
+ int get button => _button.toDartInt;
}
/// A DOM selection.
@@ -394,9 +394,9 @@
/// Inserts a rule into this style sheet.
int insertRule(String rule, [int? index]) {
if (index == null) {
- return _insertRule1(rule.toJS).toDart.toInt();
+ return _insertRule1(rule.toJS).toDartInt;
} else {
- return _insertRule2(rule.toJS, index.toDouble().toJS).toDart.toInt();
+ return _insertRule2(rule.toJS, index.toJS).toDartInt;
}
}
}
diff --git a/packages/flutter/lib/src/services/live_text.dart b/packages/flutter/lib/src/services/live_text.dart
new file mode 100644
index 0000000..413f7f0
--- /dev/null
+++ b/packages/flutter/lib/src/services/live_text.dart
@@ -0,0 +1,35 @@
+// Copyright 2014 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'system_channels.dart';
+
+/// Utility methods for interacting with the system's Live Text.
+///
+/// For example, the Live Text input feature of iOS turns the keyboard into a camera view for
+/// directly inserting text obtained through OCR into the active field.
+///
+/// See also:
+/// * <https://developer.apple.com/documentation/uikit/uiresponder/3778577-capturetextfromcamera>
+/// * <https://support.apple.com/guide/iphone/use-live-text-iphcf0b71b0e/ios>
+class LiveText {
+ // This class is not meant to be instantiated or extended; this constructor
+ // prevents instantiation and extension.
+ LiveText._();
+
+ /// Returns true if the Live Text input feature is available on the current device.
+ static Future<bool> isLiveTextInputAvailable() async {
+ final bool supportLiveTextInput =
+ await SystemChannels.platform.invokeMethod('LiveText.isLiveTextInputAvailable') ?? false;
+ return supportLiveTextInput;
+ }
+
+ /// Start Live Text input.
+ ///
+ /// If any [TextInputConnection] is currently active, calling this method will tell the text field
+ /// to start Live Text input. If the current device doesn't support Live Text input,
+ /// nothing will happen.
+ static void startLiveTextInput() {
+ SystemChannels.textInput.invokeMethod('TextInput.startLiveTextInput');
+ }
+}
diff --git a/packages/flutter/lib/src/services/text_input.dart b/packages/flutter/lib/src/services/text_input.dart
index efb4afc..f9f475f 100644
--- a/packages/flutter/lib/src/services/text_input.dart
+++ b/packages/flutter/lib/src/services/text_input.dart
@@ -1050,6 +1050,13 @@
/// Whether select all is enabled, must not be null.
bool get selectAllEnabled => true;
+ /// Whether Live Text input is enabled.
+ ///
+ /// See also:
+ /// * [LiveText], where the availability of Live Text input can be obtained.
+ /// * [LiveTextInputStatusNotifier], where the status of Live Text can be listened to.
+ bool get liveTextInputEnabled => false;
+
/// Cut current selection to [Clipboard].
///
/// If and only if [cause] is [SelectionChangedCause.toolbar], the toolbar
diff --git a/packages/flutter/lib/src/widgets/actions.dart b/packages/flutter/lib/src/widgets/actions.dart
index ce4183d..72137c0 100644
--- a/packages/flutter/lib/src/widgets/actions.dart
+++ b/packages/flutter/lib/src/widgets/actions.dart
@@ -233,8 +233,19 @@
///
/// This will be called by the [ActionDispatcher] before attempting to invoke
/// the action.
+ ///
+ /// If the action's enable state depends on a [BuildContext], subclass
+ /// [ContextAction] instead of [Action].
bool isEnabled(T intent) => isActionEnabled;
+ bool _isEnabled(T intent, BuildContext? context) {
+ final Action<T> self = this;
+ if (self is ContextAction<T>) {
+ return self.isEnabled(intent, context);
+ }
+ return self.isEnabled(intent);
+ }
+
/// Whether this [Action] is inherently enabled.
///
/// If [isActionEnabled] is false, then this [Action] is disabled for any
@@ -313,9 +324,20 @@
/// To receive the result of invoking an action, it must be invoked using
/// [Actions.invoke], or by invoking it using an [ActionDispatcher]. An action
/// invoked via a [Shortcuts] widget will have its return value ignored.
+ ///
+ /// If the action's behavior depends on a [BuildContext], subclass
+ /// [ContextAction] instead of [Action].
@protected
Object? invoke(T intent);
+ Object? _invoke(T intent, BuildContext? context) {
+ final Action<T> self = this;
+ if (self is ContextAction<T>) {
+ return self.invoke(intent, context);
+ }
+ return self.invoke(intent);
+ }
+
/// Register a callback to listen for changes to the state of this action.
///
/// If you call this, you must call [removeActionListener] a matching number
@@ -487,11 +509,22 @@
}
/// An abstract [Action] subclass that adds an optional [BuildContext] to the
-/// [invoke] method to be able to provide context to actions.
+/// [isEnabled] and [invoke] methods to be able to provide context to actions.
///
/// [ActionDispatcher.invokeAction] checks to see if the action it is invoking
/// is a [ContextAction], and if it is, supplies it with a context.
abstract class ContextAction<T extends Intent> extends Action<T> {
+ /// Returns true if the action is enabled and is ready to be invoked.
+ ///
+ /// This will be called by the [ActionDispatcher] before attempting to invoke
+ /// the action.
+ ///
+ /// The optional `context` parameter is the context of the invocation of the
+ /// action, and in the case of an action invoked by a [ShortcutManager], via
+ /// a [Shortcuts] widget, will be the context of the [Shortcuts] widget.
+ @override
+ bool isEnabled(T intent, [BuildContext? context]) => super.isEnabled(intent);
+
/// Called when the action is to be performed.
///
/// This is called by the [ActionDispatcher] when an action is invoked via
@@ -598,20 +631,47 @@
/// Returns the object returned from [Action.invoke].
///
/// The caller must receive a `true` result from [Action.isEnabled] before
- /// calling this function. This function will assert if the action is not
- /// enabled when called.
+ /// calling this function (or [ContextAction.isEnabled] with the same
+ /// `context`, if the `action` is a [ContextAction]). This function will
+ /// assert if the action is not enabled when called.
+ ///
+ /// Consider using [invokeActionIfEnabled] to invoke the action conditionally
+ /// based on whether it is enabled or not, without having to check first.
Object? invokeAction(
covariant Action<Intent> action,
covariant Intent intent, [
BuildContext? context,
]) {
- assert(action.isEnabled(intent), 'Action must be enabled when calling invokeAction');
- if (action is ContextAction) {
- context ??= primaryFocus?.context;
- return action.invoke(intent, context);
- } else {
- return action.invoke(intent);
+ final BuildContext? target = context ?? primaryFocus?.context;
+ assert(action._isEnabled(intent, target), 'Action must be enabled when calling invokeAction');
+ return action._invoke(intent, target);
+ }
+
+ /// Invokes the given `action`, passing it the given `intent`, but only if the
+ /// action is enabled.
+ ///
+ /// The action will be invoked with the given `context`, if given, but only if
+ /// the action is a [ContextAction] subclass. If no `context` is given, and
+ /// the action is a [ContextAction], then the context from the [primaryFocus]
+ /// is used.
+ ///
+ /// The return value has two components. The first is a boolean indicating if
+ /// the action was enabled (as per [Action.isEnabled]). If this is false, the
+ /// second return value is null. Otherwise, the second return value is the
+ /// object returned from [Action.invoke].
+ ///
+ /// Consider using [invokeAction] if the enabled state of the action is not in
+ /// question; this avoids calling [Action.isEnabled] redundantly.
+ (bool, Object?) invokeActionIfEnabled(
+ covariant Action<Intent> action,
+ covariant Intent intent, [
+ BuildContext? context,
+ ]) {
+ final BuildContext? target = context ?? primaryFocus?.context;
+ if (action._isEnabled(intent, target)) {
+ return (true, action._invoke(intent, target));
}
+ return (false, null);
}
}
@@ -734,11 +794,11 @@
/// [Actions.invoke] instead.
static VoidCallback? handler<T extends Intent>(BuildContext context, T intent) {
final Action<T>? action = Actions.maybeFind<T>(context);
- if (action != null && action.isEnabled(intent)) {
+ if (action != null && action._isEnabled(intent, context)) {
return () {
// Could be that the action was enabled when the closure was created,
// but is now no longer enabled, so check again.
- if (action.isEnabled(intent)) {
+ if (action._isEnabled(intent, context)) {
Actions.of(context).invokeAction(action, intent, context);
}
};
@@ -907,7 +967,7 @@
final bool actionFound = _visitActionsAncestors(context, (InheritedElement element) {
final _ActionsScope actions = element.widget as _ActionsScope;
final Action<T>? result = _castAction(actions, intent: intent);
- if (result != null && result.isEnabled(intent)) {
+ if (result != null && result._isEnabled(intent, context)) {
// Invoke the action we found using the relevant dispatcher from the Actions
// Element we found.
returnValue = _findDispatcher(element).invokeAction(result, intent, context);
@@ -954,11 +1014,10 @@
T intent,
) {
Object? returnValue;
-
_visitActionsAncestors(context, (InheritedElement element) {
final _ActionsScope actions = element.widget as _ActionsScope;
final Action<T>? result = _castAction(actions, intent: intent);
- if (result != null && result.isEnabled(intent)) {
+ if (result != null && result._isEnabled(intent, context)) {
// Invoke the action we found using the relevant dispatcher from the Actions
// element we found.
returnValue = _findDispatcher(element).invokeAction(result, intent, context);
@@ -1540,12 +1599,17 @@
/// An [Action] that iterates through a list of [Intent]s, invoking the first
/// that is enabled.
-class PrioritizedAction extends Action<PrioritizedIntents> {
+///
+/// The [isEnabled] method must be called before [invoke]. Calling [isEnabled]
+/// configures the object by seeking the first intent with an enabled action.
+/// If the actions have an opportunity to change enabled state, [isEnabled]
+/// must be called again before calling [invoke].
+class PrioritizedAction extends ContextAction<PrioritizedIntents> {
late Action<dynamic> _selectedAction;
late Intent _selectedIntent;
@override
- bool isEnabled(PrioritizedIntents intent) {
+ bool isEnabled(PrioritizedIntents intent, [ BuildContext? context ]) {
final FocusNode? focus = primaryFocus;
if (focus == null || focus.context == null) {
return false;
@@ -1555,7 +1619,7 @@
focus.context!,
intent: candidateIntent,
);
- if (candidateAction != null && candidateAction.isEnabled(candidateIntent)) {
+ if (candidateAction != null && candidateAction._isEnabled(candidateIntent, context)) {
_selectedAction = candidateAction;
_selectedIntent = candidateIntent;
return true;
@@ -1565,8 +1629,8 @@
}
@override
- void invoke(PrioritizedIntents intent) {
- _selectedAction.invoke(_selectedIntent);
+ void invoke(PrioritizedIntents intent, [ BuildContext? context ]) {
+ _selectedAction._invoke(_selectedIntent, context);
}
}
@@ -1610,9 +1674,7 @@
return true;
}());
overrideAction._updateCallingAction(defaultAction);
- final Object? returnValue = overrideAction is ContextAction<T>
- ? overrideAction.invoke(intent, context)
- : overrideAction.invoke(intent);
+ final Object? returnValue = overrideAction._invoke(intent, context);
overrideAction._updateCallingAction(null);
assert(() {
debugAssertMutuallyRecursive = false;
@@ -1656,7 +1718,7 @@
}
@override
- bool isEnabled(T intent) {
+ bool isEnabled(T intent, [BuildContext? context]) {
assert(!debugAssertIsEnabledMutuallyRecursive);
assert(() {
debugAssertIsEnabledMutuallyRecursive = true;
@@ -1665,7 +1727,7 @@
final Action<T>? overrideAction = getOverrideAction();
overrideAction?._updateCallingAction(defaultAction);
- final bool returnValue = (overrideAction ?? defaultAction).isEnabled(intent);
+ final bool returnValue = (overrideAction ?? defaultAction)._isEnabled(intent, context);
overrideAction?._updateCallingAction(null);
assert(() {
debugAssertIsEnabledMutuallyRecursive = false;
@@ -1747,9 +1809,7 @@
// calling BuildContext.
final Action<T> wrappedDefault = _ContextActionToActionAdapter<T>(invokeContext: context!, action: defaultAction);
overrideAction._updateCallingAction(wrappedDefault);
- final Object? returnValue = overrideAction is ContextAction<T>
- ? overrideAction.invoke(intent, context)
- : overrideAction.invoke(intent);
+ final Object? returnValue = overrideAction._invoke(intent, context);
overrideAction._updateCallingAction(null);
assert(() {
@@ -1790,7 +1850,7 @@
Action<T>? get callingAction => action.callingAction;
@override
- bool isEnabled(T intent) => action.isEnabled(intent);
+ bool isEnabled(T intent) => action.isEnabled(intent, invokeContext);
@override
bool get isActionEnabled => action.isActionEnabled;
diff --git a/packages/flutter/lib/src/widgets/animated_scroll_view.dart b/packages/flutter/lib/src/widgets/animated_scroll_view.dart
index a855571..8563831 100644
--- a/packages/flutter/lib/src/widgets/animated_scroll_view.dart
+++ b/packages/flutter/lib/src/widgets/animated_scroll_view.dart
@@ -6,6 +6,7 @@
import 'basic.dart';
import 'framework.dart';
+import 'media_query.dart';
import 'scroll_controller.dart';
import 'scroll_delegate.dart';
import 'scroll_physics.dart';
@@ -30,6 +31,35 @@
/// ** See code in examples/api/lib/widgets/animated_list/animated_list.0.dart **
/// {@end-tool}
///
+/// By default, [AnimatedList] will automatically pad the limits of the
+/// list's scrollable to avoid partial obstructions indicated by
+/// [MediaQuery]'s padding. To avoid this behavior, override with a
+/// zero [padding] property.
+///
+/// {@tool snippet}
+/// The following example demonstrates how to override the default top and
+/// bottom padding using [MediaQuery.removePadding].
+///
+/// ```dart
+/// Widget myWidget(BuildContext context) {
+/// return MediaQuery.removePadding(
+/// context: context,
+/// removeTop: true,
+/// removeBottom: true,
+/// child: AnimatedList(
+/// initialItemCount: 50,
+/// itemBuilder: (BuildContext context, int index, Animation<double> animation) {
+/// return Card(
+/// color: Colors.amber,
+/// child: Center(child: Text('$index')),
+/// );
+/// }
+/// ),
+/// );
+/// }
+/// ```
+/// {@end-tool}
+///
/// See also:
///
/// * [SliverAnimatedList], a sliver that animates items when they are inserted
@@ -176,6 +206,7 @@
itemBuilder: widget.itemBuilder,
initialItemCount: widget.initialItemCount,
),
+ widget.scrollDirection,
);
}
}
@@ -196,6 +227,38 @@
/// ** See code in examples/api/lib/widgets/animated_grid/animated_grid.0.dart **
/// {@end-tool}
///
+/// By default, [AnimatedGrid] will automatically pad the limits of the
+/// grid's scrollable to avoid partial obstructions indicated by
+/// [MediaQuery]'s padding. To avoid this behavior, override with a
+/// zero [padding] property.
+///
+/// {@tool snippet}
+/// The following example demonstrates how to override the default top and
+/// bottom padding using [MediaQuery.removePadding].
+///
+/// ```dart
+/// Widget myWidget(BuildContext context) {
+/// return MediaQuery.removePadding(
+/// context: context,
+/// removeTop: true,
+/// removeBottom: true,
+/// child: AnimatedGrid(
+/// gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
+/// crossAxisCount: 3,
+/// ),
+/// initialItemCount: 50,
+/// itemBuilder: (BuildContext context, int index, Animation<double> animation) {
+/// return Card(
+/// color: Colors.amber,
+/// child: Center(child: Text('$index')),
+/// );
+/// }
+/// ),
+/// );
+/// }
+/// ```
+/// {@end-tool}
+///
/// See also:
///
/// * [SliverAnimatedGrid], a sliver which animates items when they are inserted
@@ -353,6 +416,7 @@
itemBuilder: widget.itemBuilder,
initialItemCount: widget.initialItemCount,
),
+ widget.scrollDirection,
);
}
}
@@ -529,7 +593,35 @@
_sliverAnimatedMultiBoxKey.currentState!.removeAllItems(builder, duration: duration);
}
- Widget _wrap(Widget sliver) {
+ Widget _wrap(Widget sliver, Axis direction) {
+ EdgeInsetsGeometry? effectivePadding = widget.padding;
+ if (widget.padding == null) {
+ final MediaQueryData? mediaQuery = MediaQuery.maybeOf(context);
+ if (mediaQuery != null) {
+ // Automatically pad sliver with padding from MediaQuery.
+ final EdgeInsets mediaQueryHorizontalPadding =
+ mediaQuery.padding.copyWith(top: 0.0, bottom: 0.0);
+ final EdgeInsets mediaQueryVerticalPadding =
+ mediaQuery.padding.copyWith(left: 0.0, right: 0.0);
+ // Consume the main axis padding with SliverPadding.
+ effectivePadding = direction == Axis.vertical
+ ? mediaQueryVerticalPadding
+ : mediaQueryHorizontalPadding;
+ // Leave behind the cross axis padding.
+ sliver = MediaQuery(
+ data: mediaQuery.copyWith(
+ padding: direction == Axis.vertical
+ ? mediaQueryHorizontalPadding
+ : mediaQueryVerticalPadding,
+ ),
+ child: sliver,
+ );
+ }
+ }
+
+ if (effectivePadding != null) {
+ sliver = SliverPadding(padding: effectivePadding, sliver: sliver);
+ }
return CustomScrollView(
scrollDirection: widget.scrollDirection,
reverse: widget.reverse,
@@ -538,12 +630,7 @@
physics: widget.physics,
clipBehavior: widget.clipBehavior,
shrinkWrap: widget.shrinkWrap,
- slivers: <Widget>[
- SliverPadding(
- padding: widget.padding ?? EdgeInsets.zero,
- sliver: sliver,
- ),
- ],
+ slivers: <Widget>[ sliver ],
);
}
}
diff --git a/packages/flutter/lib/src/widgets/autocomplete.dart b/packages/flutter/lib/src/widgets/autocomplete.dart
index 967c116..c46d65d 100644
--- a/packages/flutter/lib/src/widgets/autocomplete.dart
+++ b/packages/flutter/lib/src/widgets/autocomplete.dart
@@ -77,6 +77,29 @@
/// * [RawAutocomplete.displayStringForOption], which is of this type.
typedef AutocompleteOptionToString<T extends Object> = String Function(T option);
+/// A direction in which to open the options-view overlay.
+///
+/// See also:
+///
+/// * [RawAutocomplete.optionsViewOpenDirection], which is of this type.
+/// * [RawAutocomplete.optionsViewBuilder] to specify how to build the
+/// selectable-options widget.
+/// * [RawAutocomplete.fieldViewBuilder] to optionally specify how to build the
+/// corresponding field widget.
+enum OptionsViewOpenDirection {
+ /// Open upward.
+ ///
+ /// The bottom edge of the options view will align with the top edge
+ /// of the text field built by [RawAutocomplete.fieldViewBuilder].
+ up,
+
+ /// Open downward.
+ ///
+ /// The top edge of the options view will align with the bottom edge
+ /// of the text field built by [RawAutocomplete.fieldViewBuilder].
+ down,
+}
+
// TODO(justinmc): Mention AutocompleteCupertino when it is implemented.
/// {@template flutter.widgets.RawAutocomplete.RawAutocomplete}
/// A widget for helping the user make a selection by entering some text and
@@ -128,6 +151,7 @@
super.key,
required this.optionsViewBuilder,
required this.optionsBuilder,
+ this.optionsViewOpenDirection = OptionsViewOpenDirection.down,
this.displayStringForOption = defaultStringForOption,
this.fieldViewBuilder,
this.focusNode,
@@ -151,6 +175,9 @@
/// Pass the provided [TextEditingController] to the field built here so that
/// RawAutocomplete can listen for changes.
/// {@endtemplate}
+ ///
+ /// If this parameter is null, then a [SizedBox.shrink] is built instead.
+ /// For how that pattern can be useful, see [textEditingController].
final AutocompleteFieldViewBuilder? fieldViewBuilder;
/// The [FocusNode] that is used for the text field.
@@ -161,9 +188,9 @@
/// field built by [fieldViewBuilder]. For example, it may be desirable to
/// place the text field in the AppBar and the options below in the main body.
///
- /// When following this pattern, [fieldViewBuilder] can return
- /// `SizedBox.shrink()` so that nothing is drawn where the text field would
- /// normally be. A separate text field can be created elsewhere, and a
+ /// When following this pattern, [fieldViewBuilder] can be omitted,
+ /// so that a text field is not drawn where it would normally be.
+ /// A separate text field can be created elsewhere, and a
/// FocusNode and TextEditingController can be passed both to that text field
/// and to RawAutocomplete.
///
@@ -182,9 +209,10 @@
/// {@template flutter.widgets.RawAutocomplete.optionsViewBuilder}
/// Builds the selectable options widgets from a list of options objects.
///
- /// The options are displayed floating below the field using a
+ /// The options are displayed floating below or above the field using a
/// [CompositedTransformFollower] inside of an [Overlay], not at the same
- /// place in the widget tree as [RawAutocomplete].
+ /// place in the widget tree as [RawAutocomplete]. To control whether it opens
+ /// upward or downward, use [optionsViewOpenDirection].
///
/// In order to track which item is highlighted by keyboard navigation, the
/// resulting options will be wrapped in an inherited
@@ -197,6 +225,13 @@
/// {@endtemplate}
final AutocompleteOptionsViewBuilder<T> optionsViewBuilder;
+ /// {@template flutter.widgets.RawAutocomplete.optionsViewOpenDirection}
+ /// The direction in which to open the options-view overlay.
+ ///
+ /// Defaults to [OptionsViewOpenDirection.down].
+ /// {@endtemplate}
+ final OptionsViewOpenDirection optionsViewOpenDirection;
+
/// {@template flutter.widgets.RawAutocomplete.displayStringForOption}
/// Returns the string to display in the field when the option is selected.
///
@@ -209,10 +244,6 @@
/// {@template flutter.widgets.RawAutocomplete.onSelected}
/// Called when an option is selected by the user.
- ///
- /// Any [TextEditingController] listeners will not be called when the user
- /// selects an option, even though the field will update with the selected
- /// value, so use this to be informed of selection.
/// {@endtemplate}
final AutocompleteOnSelected<T>? onSelected;
@@ -421,7 +452,14 @@
return CompositedTransformFollower(
link: _optionsLayerLink,
showWhenUnlinked: false,
- targetAnchor: Alignment.bottomLeft,
+ targetAnchor: switch (widget.optionsViewOpenDirection) {
+ OptionsViewOpenDirection.up => Alignment.topLeft,
+ OptionsViewOpenDirection.down => Alignment.bottomLeft,
+ },
+ followerAnchor: switch (widget.optionsViewOpenDirection) {
+ OptionsViewOpenDirection.up => Alignment.bottomLeft,
+ OptionsViewOpenDirection.down => Alignment.topLeft,
+ },
child: TextFieldTapRegion(
child: AutocompleteHighlightedOption(
highlightIndexNotifier: _highlightedOptionIndex,
diff --git a/packages/flutter/lib/src/widgets/basic.dart b/packages/flutter/lib/src/widgets/basic.dart
index 8be37bf..655b3e8 100644
--- a/packages/flutter/lib/src/widgets/basic.dart
+++ b/packages/flutter/lib/src/widgets/basic.dart
@@ -2263,7 +2263,7 @@
final MultiChildLayoutParentData parentData = renderObject.parentData! as MultiChildLayoutParentData;
if (parentData.id != id) {
parentData.id = id;
- final AbstractNode? targetParent = renderObject.parent;
+ final RenderObject? targetParent = renderObject.parent;
if (targetParent is RenderObject) {
targetParent.markNeedsLayout();
}
@@ -3036,6 +3036,12 @@
/// A widget that imposes different constraints on its child than it gets
/// from its parent, possibly allowing the child to overflow the parent.
///
+/// {@tool dartpad}
+/// This example shows how an [OverflowBox] is used, and what its effect is.
+///
+/// ** See code in examples/api/lib/widgets/basic/overflowbox.0.dart **
+/// {@end-tool}
+///
/// See also:
///
/// * [RenderConstrainedOverflowBox] for details about how [OverflowBox] is
@@ -4348,7 +4354,7 @@
}
if (needsLayout) {
- final AbstractNode? targetParent = renderObject.parent;
+ final RenderObject? targetParent = renderObject.parent;
if (targetParent is RenderObject) {
targetParent.markNeedsLayout();
}
@@ -5207,7 +5213,7 @@
}
if (needsLayout) {
- final AbstractNode? targetParent = renderObject.parent;
+ final RenderObject? targetParent = renderObject.parent;
if (targetParent is RenderObject) {
targetParent.markNeedsLayout();
}
diff --git a/packages/flutter/lib/src/widgets/container.dart b/packages/flutter/lib/src/widgets/container.dart
index 9202d7f..486bce7 100644
--- a/packages/flutter/lib/src/widgets/container.dart
+++ b/packages/flutter/lib/src/widgets/container.dart
@@ -52,6 +52,7 @@
/// * [Decoration], which you can extend to provide other effects with
/// [DecoratedBox].
/// * [CustomPaint], another way to draw custom effects from the widget layer.
+/// * [DecoratedSliver], which applies a [Decoration] to a sliver.
class DecoratedBox extends SingleChildRenderObjectWidget {
/// Creates a widget that paints a [Decoration].
///
diff --git a/packages/flutter/lib/src/widgets/context_menu_button_item.dart b/packages/flutter/lib/src/widgets/context_menu_button_item.dart
index 8240d9b..e355ab4 100644
--- a/packages/flutter/lib/src/widgets/context_menu_button_item.dart
+++ b/packages/flutter/lib/src/widgets/context_menu_button_item.dart
@@ -26,6 +26,13 @@
/// A button that deletes the current text selection.
delete,
+ /// A button for starting Live Text input.
+ ///
+ /// See also:
+ /// * [LiveText], where the availability of Live Text input can be obtained.
+ /// * [LiveTextInputStatusNotifier], where the status of Live Text can be listened to.
+ liveTextInput,
+
/// Anything other than the default button types.
custom,
}
diff --git a/packages/flutter/lib/src/widgets/decorated_sliver.dart b/packages/flutter/lib/src/widgets/decorated_sliver.dart
new file mode 100644
index 0000000..fffe3b4
--- /dev/null
+++ b/packages/flutter/lib/src/widgets/decorated_sliver.dart
@@ -0,0 +1,90 @@
+// Copyright 2014 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'package:flutter/rendering.dart';
+
+import 'basic.dart';
+import 'framework.dart';
+import 'image.dart';
+
+/// A sliver widget that paints a [Decoration] either before or after its child
+/// paints.
+///
+/// Unlike [DecoratedBox], this widget expects its child to be a sliver, and
+/// must be placed in a widget that expects a sliver.
+///
+/// If the child sliver has infinite [SliverGeometry.scrollExtent], then we only
+/// draw the decoration down to the bottom [SliverGeometry.cacheExtent], and
+/// it is necessary to ensure that the bottom border does not creep
+/// above the top of the bottom cache. This can happen if the bottom has a
+/// border radius larger than the extent of the cache area.
+///
+/// Commonly used with [BoxDecoration].
+///
+/// The [child] is not clipped. To clip a child to the shape of a particular
+/// [ShapeDecoration], consider using a [ClipPath] widget.
+///
+/// {@tool dartpad}
+/// This sample shows a radial gradient that draws a moon on a night sky:
+///
+/// ** See code in examples/api/lib/widgets/sliver/decorated_sliver.0.dart **
+/// {@end-tool}
+///
+/// See also:
+///
+/// * [DecoratedBox], the version of this class that works with RenderBox widgets.
+/// * [Decoration], which you can extend to provide other effects with
+/// [DecoratedSliver].
+/// * [CustomPaint], another way to draw custom effects from the widget layer.
+class DecoratedSliver extends SingleChildRenderObjectWidget {
+ /// Creates a widget that paints a [Decoration].
+ ///
+ /// The [decoration] and [position] arguments must not be null. By default the
+ /// decoration paints behind the child.
+ const DecoratedSliver({
+ super.key,
+ required this.decoration,
+ this.position = DecorationPosition.background,
+ Widget? sliver,
+ }) : super(child: sliver);
+
+ /// What decoration to paint.
+ ///
+ /// Commonly a [BoxDecoration].
+ final Decoration decoration;
+
+ /// Whether to paint the box decoration behind or in front of the child.
+ final DecorationPosition position;
+
+ @override
+ RenderDecoratedSliver createRenderObject(BuildContext context) {
+ return RenderDecoratedSliver(
+ decoration: decoration,
+ position: position,
+ configuration: createLocalImageConfiguration(context),
+ );
+ }
+
+ @override
+ void updateRenderObject(BuildContext context, RenderDecoratedSliver renderObject) {
+ renderObject
+ ..decoration = decoration
+ ..position = position
+ ..configuration = createLocalImageConfiguration(context);
+ }
+
+ @override
+ void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+ super.debugFillProperties(properties);
+ final String label;
+ switch (position) {
+ case DecorationPosition.background:
+ label = 'bg';
+ case DecorationPosition.foreground:
+ label = 'fg';
+ }
+ properties.add(EnumProperty<DecorationPosition>('position', position, level: DiagnosticLevel.hidden));
+ properties.add(DiagnosticsProperty<Decoration>(label, decoration));
+ }
+}
diff --git a/packages/flutter/lib/src/widgets/editable_text.dart b/packages/flutter/lib/src/widgets/editable_text.dart
index 32defb1..859dfa8 100644
--- a/packages/flutter/lib/src/widgets/editable_text.dart
+++ b/packages/flutter/lib/src/widgets/editable_text.dart
@@ -1835,36 +1835,48 @@
required final VoidCallback? onCut,
required final VoidCallback? onPaste,
required final VoidCallback? onSelectAll,
+ required final VoidCallback? onLiveTextInput,
}) {
- // If the paste button is enabled, don't render anything until the state
- // of the clipboard is known, since it's used to determine if paste is
- // shown.
- if (onPaste != null && clipboardStatus == ClipboardStatus.unknown) {
- return <ContextMenuButtonItem>[];
+ final List<ContextMenuButtonItem> resultButtonItem = <ContextMenuButtonItem>[];
+
+ // Configure button items with clipboard.
+ if (onPaste == null || clipboardStatus != ClipboardStatus.unknown) {
+ // If the paste button is enabled, don't render anything until the state
+ // of the clipboard is known, since it's used to determine if paste is
+ // shown.
+ resultButtonItem.addAll(<ContextMenuButtonItem>[
+ if (onCut != null)
+ ContextMenuButtonItem(
+ onPressed: onCut,
+ type: ContextMenuButtonType.cut,
+ ),
+ if (onCopy != null)
+ ContextMenuButtonItem(
+ onPressed: onCopy,
+ type: ContextMenuButtonType.copy,
+ ),
+ if (onPaste != null)
+ ContextMenuButtonItem(
+ onPressed: onPaste,
+ type: ContextMenuButtonType.paste,
+ ),
+ if (onSelectAll != null)
+ ContextMenuButtonItem(
+ onPressed: onSelectAll,
+ type: ContextMenuButtonType.selectAll,
+ ),
+ ]);
}
- return <ContextMenuButtonItem>[
- if (onCut != null)
- ContextMenuButtonItem(
- onPressed: onCut,
- type: ContextMenuButtonType.cut,
- ),
- if (onCopy != null)
- ContextMenuButtonItem(
- onPressed: onCopy,
- type: ContextMenuButtonType.copy,
- ),
- if (onPaste != null)
- ContextMenuButtonItem(
- onPressed: onPaste,
- type: ContextMenuButtonType.paste,
- ),
- if (onSelectAll != null)
- ContextMenuButtonItem(
- onPressed: onSelectAll,
- type: ContextMenuButtonType.selectAll,
- ),
- ];
+ // Config button items with Live Text.
+ if (onLiveTextInput != null) {
+ resultButtonItem.add(ContextMenuButtonItem(
+ onPressed: onLiveTextInput,
+ type: ContextMenuButtonType.liveTextInput,
+ ));
+ }
+
+ return resultButtonItem;
}
// Infer the keyboard type of an `EditableText` if it's not specified.
@@ -2063,6 +2075,13 @@
/// Detects whether the clipboard can paste.
final ClipboardStatusNotifier clipboardStatus = ClipboardStatusNotifier();
+ /// Detects whether the Live Text input is enabled.
+ ///
+ /// See also:
+ /// * [LiveText], where the availability of Live Text input can be obtained.
+ final LiveTextInputStatusNotifier? _liveTextInputStatus =
+ kIsWeb ? null : LiveTextInputStatusNotifier();
+
TextInputConnection? _textInputConnection;
bool get _hasInputConnection => _textInputConnection?.attached ?? false;
@@ -2196,12 +2215,26 @@
}
}
+ @override
+ bool get liveTextInputEnabled {
+ return _liveTextInputStatus?.value == LiveTextInputStatus.enabled &&
+ !widget.obscureText &&
+ !widget.readOnly &&
+ textEditingValue.selection.isCollapsed;
+ }
+
void _onChangedClipboardStatus() {
setState(() {
// Inform the widget that the value of clipboardStatus has changed.
});
}
+ void _onChangedLiveTextInputStatus() {
+ setState(() {
+ // Inform the widget that the value of liveTextInputStatus has changed.
+ });
+ }
+
TextEditingValue get _textEditingValueforTextLayoutMetrics {
final Widget? editableWidget =_editableKey.currentContext?.widget;
if (editableWidget is! _Editable) {
@@ -2347,6 +2380,18 @@
}
}
+ void _startLiveTextInput(SelectionChangedCause cause) {
+ if (!liveTextInputEnabled) {
+ return;
+ }
+ if (_hasInputConnection) {
+ LiveText.startLiveTextInput();
+ }
+ if (cause == SelectionChangedCause.toolbar) {
+ hideToolbar();
+ }
+ }
+
/// Finds specified [SuggestionSpan] that matches the provided index using
/// binary search.
///
@@ -2561,6 +2606,9 @@
onSelectAll: selectAllEnabled
? () => selectAll(SelectionChangedCause.toolbar)
: null,
+ onLiveTextInput: liveTextInputEnabled
+ ? () => _startLiveTextInput(SelectionChangedCause.toolbar)
+ : null,
);
}
@@ -2569,6 +2617,7 @@
@override
void initState() {
super.initState();
+ _liveTextInputStatus?.addListener(_onChangedLiveTextInputStatus);
clipboardStatus.addListener(_onChangedClipboardStatus);
widget.controller.addListener(_didChangeTextEditingValue);
widget.focusNode.addListener(_handleFocusChanged);
@@ -2734,6 +2783,8 @@
_selectionOverlay = null;
widget.focusNode.removeListener(_handleFocusChanged);
WidgetsBinding.instance.removeObserver(this);
+ _liveTextInputStatus?.removeListener(_onChangedLiveTextInputStatus);
+ _liveTextInputStatus?.dispose();
clipboardStatus.removeListener(_onChangedClipboardStatus);
clipboardStatus.dispose();
_cursorVisibilityNotifier.dispose();
@@ -2819,17 +2870,17 @@
_formatAndSetValue(value, SelectionChangedCause.keyboard);
}
+ if (_showBlinkingCursor && _cursorTimer != null) {
+ // To keep the cursor from blinking while typing, restart the timer here.
+ _stopCursorBlink(resetCharTicks: false);
+ _startCursorBlink();
+ }
+
// Wherever the value is changed by the user, schedule a showCaretOnScreen
// to make sure the user can see the changes they just made. Programmatic
// changes to `textEditingValue` do not trigger the behavior even if the
// text field is focused.
_scheduleShowCaretOnScreen(withAnimation: true);
- if (_hasInputConnection) {
- // To keep the cursor from blinking while typing, we want to restart the
- // cursor timer every time a new character is typed.
- _stopCursorBlink(resetCharTicks: false);
- _startCursorBlink();
- }
}
bool _checkNeedsAdjustAffinity(TextEditingValue value) {
@@ -3415,18 +3466,12 @@
}
// To keep the cursor from blinking while it moves, restart the timer here.
- if (_cursorTimer != null) {
+ if (_showBlinkingCursor && _cursorTimer != null) {
_stopCursorBlink(resetCharTicks: false);
_startCursorBlink();
}
}
- Rect? _currentCaretRect;
- // ignore: use_setters_to_change_properties, (this is used as a callback, can't be a setter)
- void _handleCaretChanged(Rect caretRect) {
- _currentCaretRect = caretRect;
- }
-
// Animation configuration for scrolling the caret back on screen.
static const Duration _caretAnimationDuration = Duration(milliseconds: 100);
static const Curve _caretAnimationCurve = Curves.fastOutSlowIn;
@@ -3440,7 +3485,13 @@
_showCaretOnScreenScheduled = true;
SchedulerBinding.instance.addPostFrameCallback((Duration _) {
_showCaretOnScreenScheduled = false;
- if (_currentCaretRect == null || !_scrollController.hasClients) {
+ // Since we are in a post frame callback, check currentContext in case
+ // RenderEditable has been disposed (in which case it will be null).
+ final RenderEditable? renderEditable =
+ _editableKey.currentContext?.findRenderObject() as RenderEditable?;
+ if (renderEditable == null
+ || !(renderEditable.selection?.isValid ?? false)
+ || !_scrollController.hasClients) {
return;
}
@@ -3471,7 +3522,8 @@
final EdgeInsets caretPadding = widget.scrollPadding
.copyWith(bottom: bottomSpacing);
- final RevealedOffset targetOffset = _getOffsetToRevealCaret(_currentCaretRect!);
+ final Rect caretRect = renderEditable.getLocalRectForCaret(renderEditable.selection!.extent);
+ final RevealedOffset targetOffset = _getOffsetToRevealCaret(caretRect);
final Rect rectToReveal;
final TextSelection selection = textEditingValue.selection;
@@ -3985,6 +4037,7 @@
if (_selectionOverlay == null) {
return false;
}
+ _liveTextInputStatus?.update();
clipboardStatus.update();
_selectionOverlay!.showToolbar();
return true;
@@ -4644,7 +4697,6 @@
obscuringCharacter: widget.obscuringCharacter,
obscureText: widget.obscureText,
offset: offset,
- onCaretChanged: _handleCaretChanged,
rendererIgnoresPointer: widget.rendererIgnoresPointer,
cursorWidth: widget.cursorWidth,
cursorHeight: widget.cursorHeight,
@@ -4769,7 +4821,6 @@
required this.obscuringCharacter,
required this.obscureText,
required this.offset,
- this.onCaretChanged,
this.rendererIgnoresPointer = false,
required this.cursorWidth,
this.cursorHeight,
@@ -4810,7 +4861,6 @@
final TextHeightBehavior? textHeightBehavior;
final TextWidthBasis textWidthBasis;
final ViewportOffset offset;
- final CaretChangedHandler? onCaretChanged;
final bool rendererIgnoresPointer;
final double cursorWidth;
final double? cursorHeight;
@@ -4849,7 +4899,6 @@
locale: locale ?? Localizations.maybeLocaleOf(context),
selection: value.selection,
offset: offset,
- onCaretChanged: onCaretChanged,
ignorePointer: rendererIgnoresPointer,
obscuringCharacter: obscuringCharacter,
obscureText: obscureText,
@@ -4894,7 +4943,6 @@
..locale = locale ?? Localizations.maybeLocaleOf(context)
..selection = value.selection
..offset = offset
- ..onCaretChanged = onCaretChanged
..ignorePointer = rendererIgnoresPointer
..textHeightBehavior = textHeightBehavior
..textWidthBasis = textWidthBasis
diff --git a/packages/flutter/lib/src/widgets/framework.dart b/packages/flutter/lib/src/widgets/framework.dart
index b2f3d96..c6d8f05 100644
--- a/packages/flutter/lib/src/widgets/framework.dart
+++ b/packages/flutter/lib/src/widgets/framework.dart
@@ -4,7 +4,6 @@
import 'dart:async';
import 'dart:collection';
-import 'dart:developer';
import 'package:flutter/foundation.dart';
import 'package:flutter/rendering.dart';
@@ -2700,7 +2699,7 @@
}
return true;
}());
- Timeline.startSync(
+ FlutterTimeline.startSync(
'BUILD',
arguments: debugTimelineArguments
);
@@ -2771,7 +2770,7 @@
}
return true;
}());
- Timeline.startSync(
+ FlutterTimeline.startSync(
'${element.widget.runtimeType}',
arguments: debugTimelineArguments,
);
@@ -2794,7 +2793,7 @@
);
}
if (isTimelineTracked) {
- Timeline.finishSync();
+ FlutterTimeline.finishSync();
}
index += 1;
if (dirtyCount < _dirtyElements.length || _dirtyElementsNeedsResorting!) {
@@ -2832,7 +2831,7 @@
_scheduledFlushDirtyElements = false;
_dirtyElementsNeedsResorting = null;
if (!kReleaseMode) {
- Timeline.finishSync();
+ FlutterTimeline.finishSync();
}
assert(_debugBuilding);
assert(() {
@@ -3044,7 +3043,7 @@
@pragma('vm:notify-debugger-on-exception')
void finalizeTree() {
if (!kReleaseMode) {
- Timeline.startSync('FINALIZE TREE');
+ FlutterTimeline.startSync('FINALIZE TREE');
}
try {
lockState(_inactiveElements._unmountAll); // this unregisters the GlobalKeys
@@ -3140,7 +3139,7 @@
_reportException(ErrorSummary('while finalizing the widget tree'), e, stack);
} finally {
if (!kReleaseMode) {
- Timeline.finishSync();
+ FlutterTimeline.finishSync();
}
}
}
@@ -3153,7 +3152,7 @@
/// This is expensive and should not be called except during development.
void reassemble(Element root, DebugReassembleConfig? reassembleConfig) {
if (!kReleaseMode) {
- Timeline.startSync('Preparing Hot Reload (widgets)');
+ FlutterTimeline.startSync('Preparing Hot Reload (widgets)');
}
try {
assert(root._parent == null);
@@ -3162,7 +3161,7 @@
root.reassemble();
} finally {
if (!kReleaseMode) {
- Timeline.finishSync();
+ FlutterTimeline.finishSync();
}
}
}
@@ -3678,14 +3677,14 @@
}
return true;
}());
- Timeline.startSync(
+ FlutterTimeline.startSync(
'${newWidget.runtimeType}',
arguments: debugTimelineArguments,
);
}
child.update(newWidget);
if (isTimelineTracked) {
- Timeline.finishSync();
+ FlutterTimeline.finishSync();
}
assert(child.widget == newWidget);
assert(() {
@@ -4153,7 +4152,7 @@
}
return true;
}());
- Timeline.startSync(
+ FlutterTimeline.startSync(
'${newWidget.runtimeType}',
arguments: debugTimelineArguments,
);
@@ -4186,7 +4185,7 @@
return newChild;
} finally {
if (isTimelineTracked) {
- Timeline.finishSync();
+ FlutterTimeline.finishSync();
}
}
}
@@ -4795,7 +4794,7 @@
final List<DiagnosticsNode> diagnosticsDependencies = sortedDependencies
.map((InheritedElement element) => element.widget.toDiagnosticsNode(style: DiagnosticsTreeStyle.sparse))
.toList();
- properties.add(DiagnosticsProperty<List<DiagnosticsNode>>('dependencies', diagnosticsDependencies));
+ properties.add(DiagnosticsProperty<Set<InheritedElement>>('dependencies', deps, description: diagnosticsDependencies.toString()));
}
}
diff --git a/packages/flutter/lib/src/widgets/media_query.dart b/packages/flutter/lib/src/widgets/media_query.dart
index 8cd8ee3..0714708 100644
--- a/packages/flutter/lib/src/widgets/media_query.dart
+++ b/packages/flutter/lib/src/widgets/media_query.dart
@@ -60,6 +60,8 @@
invertColors,
/// Specifies the aspect corresponding to [MediaQueryData.highContrast].
highContrast,
+ /// Specifies the aspect corresponding to [MediaQueryData.onOffSwitchLabels].
+ onOffSwitchLabels,
/// Specifies the aspect corresponding to [MediaQueryData.disableAnimations].
disableAnimations,
/// Specifies the aspect corresponding to [MediaQueryData.boldText].
@@ -153,6 +155,7 @@
this.accessibleNavigation = false,
this.invertColors = false,
this.highContrast = false,
+ this.onOffSwitchLabels = false,
this.disableAnimations = false,
this.boldText = false,
this.navigationMode = NavigationMode.traditional,
@@ -220,6 +223,7 @@
disableAnimations = platformData?.disableAnimations ?? view.platformDispatcher.accessibilityFeatures.disableAnimations,
boldText = platformData?.boldText ?? view.platformDispatcher.accessibilityFeatures.boldText,
highContrast = platformData?.highContrast ?? view.platformDispatcher.accessibilityFeatures.highContrast,
+ onOffSwitchLabels = platformData?.onOffSwitchLabels ?? view.platformDispatcher.accessibilityFeatures.onOffSwitchLabels,
alwaysUse24HourFormat = platformData?.alwaysUse24HourFormat ?? view.platformDispatcher.alwaysUse24HourFormat,
navigationMode = platformData?.navigationMode ?? NavigationMode.traditional,
gestureSettings = DeviceGestureSettings.fromView(view),
@@ -416,6 +420,15 @@
/// or above.
final bool highContrast;
+ /// Whether the user requested to show on/off labels inside switches on iOS,
+ /// via Settings -> Accessibility -> Display & Text Size -> On/Off Labels.
+ ///
+ /// See also:
+ ///
+ /// * [dart:ui.PlatformDispatcher.accessibilityFeatures], where the setting
+ /// originates.
+ final bool onOffSwitchLabels;
+
/// Whether the platform is requesting that animations be disabled or reduced
/// as much as possible.
///
@@ -488,6 +501,7 @@
EdgeInsets? systemGestureInsets,
bool? alwaysUse24HourFormat,
bool? highContrast,
+ bool? onOffSwitchLabels,
bool? disableAnimations,
bool? invertColors,
bool? accessibleNavigation,
@@ -508,6 +522,7 @@
alwaysUse24HourFormat: alwaysUse24HourFormat ?? this.alwaysUse24HourFormat,
invertColors: invertColors ?? this.invertColors,
highContrast: highContrast ?? this.highContrast,
+ onOffSwitchLabels: onOffSwitchLabels ?? this.onOffSwitchLabels,
disableAnimations: disableAnimations ?? this.disableAnimations,
accessibleNavigation: accessibleNavigation ?? this.accessibleNavigation,
boldText: boldText ?? this.boldText,
@@ -699,6 +714,7 @@
&& other.systemGestureInsets == systemGestureInsets
&& other.alwaysUse24HourFormat == alwaysUse24HourFormat
&& other.highContrast == highContrast
+ && other.onOffSwitchLabels == onOffSwitchLabels
&& other.disableAnimations == disableAnimations
&& other.invertColors == invertColors
&& other.accessibleNavigation == accessibleNavigation
@@ -719,6 +735,7 @@
viewInsets,
alwaysUse24HourFormat,
highContrast,
+ onOffSwitchLabels,
disableAnimations,
invertColors,
accessibleNavigation,
@@ -742,6 +759,7 @@
'alwaysUse24HourFormat: $alwaysUse24HourFormat',
'accessibleNavigation: $accessibleNavigation',
'highContrast: $highContrast',
+ 'onOffSwitchLabels: $onOffSwitchLabels',
'disableAnimations: $disableAnimations',
'invertColors: $invertColors',
'boldText: $boldText',
@@ -1255,6 +1273,25 @@
/// the [MediaQueryData.highContrast] property of the ancestor [MediaQuery] changes.
static bool? maybeHighContrastOf(BuildContext context) => _maybeOf(context, _MediaQueryAspect.highContrast)?.highContrast;
+ /// Returns onOffSwitchLabels for the nearest MediaQuery ancestor or false, if no
+ /// such ancestor exists.
+ ///
+ /// See also:
+ ///
+ /// * [MediaQueryData.onOffSwitchLabels], which indicates the platform's
+ /// desire to show on/off labels inside switches.
+ ///
+ /// Use of this method will cause the given [context] to rebuild any time that
+ /// the [MediaQueryData.onOffSwitchLabels] property of the ancestor [MediaQuery] changes.
+ static bool onOffSwitchLabelsOf(BuildContext context) => maybeOnOffSwitchLabelsOf(context) ?? false;
+
+ /// Returns onOffSwitchLabels for the nearest MediaQuery ancestor or
+ /// null, if no such ancestor exists.
+ ///
+ /// Use of this method will cause the given [context] to rebuild any time that
+ /// the [MediaQueryData.onOffSwitchLabels] property of the ancestor [MediaQuery] changes.
+ static bool? maybeOnOffSwitchLabelsOf(BuildContext context) => _maybeOf(context, _MediaQueryAspect.onOffSwitchLabels)?.onOffSwitchLabels;
+
/// Returns disableAnimations for the nearest MediaQuery ancestor or
/// [Brightness.light], if no such ancestor exists.
///
@@ -1406,6 +1443,10 @@
if (data.highContrast != oldWidget.data.highContrast) {
return true;
}
+ case _MediaQueryAspect.onOffSwitchLabels:
+ if (data.onOffSwitchLabels != oldWidget.data.onOffSwitchLabels) {
+ return true;
+ }
case _MediaQueryAspect.disableAnimations:
if (data.disableAnimations != oldWidget.data.disableAnimations) {
return true;
diff --git a/packages/flutter/lib/src/widgets/overlay.dart b/packages/flutter/lib/src/widgets/overlay.dart
index aad2536..6b24276 100644
--- a/packages/flutter/lib/src/widgets/overlay.dart
+++ b/packages/flutter/lib/src/widgets/overlay.dart
@@ -936,6 +936,14 @@
@override
void redepthChildren() => visitChildren(redepthChild);
+ void _adoptDeferredLayoutBoxChild(_RenderDeferredLayoutBox child) {
+ adoptChild(child);
+ }
+
+ void _dropDeferredLayoutBoxChild(_RenderDeferredLayoutBox child) {
+ dropChild(child);
+ }
+
Alignment? _alignmentCache;
Alignment get _resolvedAlignment => _alignmentCache ??= AlignmentDirectional.topStart.resolve(textDirection);
@@ -1492,47 +1500,35 @@
// used as the slot of the overlay child widget.
//
// The developer must call `show` to reveal the overlay so we can get a unique
- // timestamp of the user interaction for sorting.
+ // timestamp of the user interaction for determining the z-index of the
+ // overlay child in the overlay.
//
// Avoid invalidating the cache if possible, since the framework uses `==` to
// compare slots, and _OverlayEntryLocation can't override that operator since
- // it's mutable.
+ // it's mutable. Changing slots can be relatively slow.
bool _childModelMayHaveChanged = true;
_OverlayEntryLocation? _locationCache;
+ static bool _isTheSameLocation(_OverlayEntryLocation locationCache, _RenderTheaterMarker marker) {
+ return locationCache._childModel == marker.overlayEntryWidgetState
+ && locationCache._theater == marker.theater;
+ }
+
_OverlayEntryLocation _getLocation(int zOrderIndex, bool targetRootOverlay) {
final _OverlayEntryLocation? cachedLocation = _locationCache;
- if (cachedLocation != null && !_childModelMayHaveChanged) {
+ late final _RenderTheaterMarker marker = _RenderTheaterMarker.of(context, targetRootOverlay: targetRootOverlay);
+ final bool isCacheValid = cachedLocation != null
+ && (!_childModelMayHaveChanged || _isTheSameLocation(cachedLocation, marker));
+ _childModelMayHaveChanged = false;
+ if (isCacheValid) {
assert(cachedLocation._zOrderIndex == zOrderIndex);
+ assert(cachedLocation._debugIsLocationValid());
return cachedLocation;
}
- _childModelMayHaveChanged = false;
- final _RenderTheaterMarker? marker = _RenderTheaterMarker.maybeOf(context, targetRootOverlay: targetRootOverlay);
- if (marker == null) {
- throw FlutterError.fromParts(<DiagnosticsNode>[
- ErrorSummary('No Overlay widget found.'),
- ErrorDescription(
- '${widget.runtimeType} widgets require an Overlay widget ancestor.\n'
- 'An overlay lets widgets float on top of other widget children.',
- ),
- ErrorHint(
- 'To introduce an Overlay widget, you can either directly '
- 'include one, or use a widget that contains an Overlay itself, '
- 'such as a Navigator, WidgetApp, MaterialApp, or CupertinoApp.',
- ),
- ...context.describeMissingAncestor(expectedAncestorType: Overlay),
- ]);
- }
- final _OverlayEntryLocation returnValue;
- if (cachedLocation == null) {
- returnValue = _OverlayEntryLocation(zOrderIndex, marker.overlayEntryWidgetState, marker.theater);
- } else if (cachedLocation._childModel != marker.overlayEntryWidgetState || cachedLocation._theater != marker.theater) {
- cachedLocation._dispose();
- returnValue = _OverlayEntryLocation(zOrderIndex, marker.overlayEntryWidgetState, marker.theater);
- } else {
- returnValue = cachedLocation;
- }
- assert(returnValue._zOrderIndex == zOrderIndex);
- return _locationCache = returnValue;
+ // Otherwise invalidate the cache and create a new location.
+ cachedLocation?._debugMarkLocationInvalid();
+ final _OverlayEntryLocation newLocation = _OverlayEntryLocation(zOrderIndex, marker.overlayEntryWidgetState, marker.theater);
+ assert(newLocation._zOrderIndex == zOrderIndex);
+ return _locationCache = newLocation;
}
@override
@@ -1573,8 +1569,9 @@
@override
void dispose() {
+ assert(widget.controller._attachTarget == this);
widget.controller._attachTarget = null;
- _locationCache?._dispose();
+ _locationCache?._debugMarkLocationInvalid();
_locationCache = null;
super.dispose();
}
@@ -1585,14 +1582,14 @@
'${widget.controller.runtimeType}.show() should not be called during build.'
);
setState(() { _zOrderIndex = zOrderIndex; });
- _locationCache?._dispose();
+ _locationCache?._debugMarkLocationInvalid();
_locationCache = null;
}
void hide() {
assert(SchedulerBinding.instance.schedulerPhase != SchedulerPhase.persistentCallbacks);
setState(() { _zOrderIndex = null; });
- _locationCache?._dispose();
+ _locationCache?._debugMarkLocationInvalid();
_locationCache = null;
}
@@ -1673,7 +1670,7 @@
}
void _addChild(_RenderDeferredLayoutBox child) {
- assert(_debugNotDisposed());
+ assert(_debugIsLocationValid());
_addToChildModel(child);
_theater._addDeferredChild(child);
assert(child.parent == _theater);
@@ -1688,7 +1685,7 @@
void _moveChild(_RenderDeferredLayoutBox child, _OverlayEntryLocation fromLocation) {
assert(fromLocation != this);
- assert(_debugNotDisposed());
+ assert(_debugIsLocationValid());
final _RenderTheater fromTheater = fromLocation._theater;
final _OverlayEntryWidgetState fromModel = fromLocation._childModel;
@@ -1704,34 +1701,54 @@
}
void _activate(_RenderDeferredLayoutBox child) {
- assert(_debugNotDisposed());
+ // This call is allowed even when this location is invalidated.
+ // See _OverlayPortalElement.activate.
assert(_overlayChildRenderBox == null, '$_overlayChildRenderBox');
- _theater.adoptChild(child);
+ _theater._adoptDeferredLayoutBoxChild(child);
_overlayChildRenderBox = child;
}
void _deactivate(_RenderDeferredLayoutBox child) {
- assert(_debugNotDisposed());
- _theater.dropChild(child);
+ // This call is allowed even when this location is invalidated.
+ _theater._dropDeferredLayoutBoxChild(child);
_overlayChildRenderBox = null;
}
- bool _debugNotDisposed() {
- if (_debugDisposedStackTrace == null) {
+ // Throws a StateError if this location is already invalidated and shouldn't
+ // be used as an OverlayPortal slot. Must be used in asserts.
+ //
+ // Generally, `assert(_debugIsLocationValid())` should be used to prevent
+ // invalid accesses to an invalid `_OverlayEntryLocation` object. Exceptions
+ // to this rule are _removeChild, _deactive, which will be called when the
+ // OverlayPortal is being removed from the widget tree and may use the
+ // location information to perform cleanup tasks.
+ //
+ // Another exception is the _activate method which is called by
+ // _OverlayPortalElement.activate. See the comment in _OverlayPortalElement.activate.
+ bool _debugIsLocationValid() {
+ if (_debugMarkLocationInvalidStackTrace == null) {
return true;
}
- throw StateError('$this is already disposed. Stack trace: $_debugDisposedStackTrace');
+ throw StateError('$this is already disposed. Stack trace: $_debugMarkLocationInvalidStackTrace');
}
- StackTrace? _debugDisposedStackTrace;
+ // The StackTrace of the first _debugMarkLocationInvalid call. It's only for
+ // debugging purposes and the StackTrace will only be captured in debug builds.
+ //
+ // The effect of this method is not reversible. Once marked invalid, this
+ // object can't be marked as valid again.
+ StackTrace? _debugMarkLocationInvalidStackTrace;
@mustCallSuper
- void _dispose() {
- assert(_debugNotDisposed());
+ void _debugMarkLocationInvalid() {
+ assert(_debugIsLocationValid());
assert(() {
- _debugDisposedStackTrace = StackTrace.current;
+ _debugMarkLocationInvalidStackTrace = StackTrace.current;
return true;
}());
}
+
+ @override
+ String toString() => '${objectRuntimeType(this, '_OverlayEntryLocation')}[${shortHash(this)}] ${_debugMarkLocationInvalidStackTrace != null ? "(INVALID)":""}';
}
class _RenderTheaterMarker extends InheritedWidget {
@@ -1750,13 +1767,31 @@
|| oldWidget.overlayEntryWidgetState != overlayEntryWidgetState;
}
- static _RenderTheaterMarker? maybeOf(BuildContext context, { bool targetRootOverlay = false }) {
+ static _RenderTheaterMarker of(BuildContext context, { bool targetRootOverlay = false }) {
+ final _RenderTheaterMarker? marker;
if (targetRootOverlay) {
final InheritedElement? ancestor = _rootRenderTheaterMarkerOf(context.getElementForInheritedWidgetOfExactType<_RenderTheaterMarker>());
assert(ancestor == null || ancestor.widget is _RenderTheaterMarker);
- return ancestor != null ? context.dependOnInheritedElement(ancestor) as _RenderTheaterMarker? : null;
+ marker = ancestor != null ? context.dependOnInheritedElement(ancestor) as _RenderTheaterMarker? : null;
+ } else {
+ marker = context.dependOnInheritedWidgetOfExactType<_RenderTheaterMarker>();
}
- return context.dependOnInheritedWidgetOfExactType<_RenderTheaterMarker>();
+ if (marker != null) {
+ return marker;
+ }
+ throw FlutterError.fromParts(<DiagnosticsNode>[
+ ErrorSummary('No Overlay widget found.'),
+ ErrorDescription(
+ '${context.widget.runtimeType} widgets require an Overlay widget ancestor.\n'
+ 'An overlay lets widgets float on top of other widget children.',
+ ),
+ ErrorHint(
+ 'To introduce an Overlay widget, you can either directly '
+ 'include one, or use a widget that contains an Overlay itself, '
+ 'such as a Navigator, WidgetApp, MaterialApp, or CupertinoApp.',
+ ),
+ ...context.describeMissingAncestor(expectedAncestorType: Overlay),
+ ]);
}
static InheritedElement? _rootRenderTheaterMarkerOf(InheritedElement? theaterMarkerElement) {
@@ -1784,7 +1819,7 @@
required this.overlayChild,
required this.child,
}) : assert(overlayChild == null || overlayLocation != null),
- assert(overlayLocation == null || overlayLocation._debugNotDisposed());
+ assert(overlayLocation == null || overlayLocation._debugIsLocationValid());
final Widget? overlayChild;
@@ -1855,6 +1890,9 @@
if (box != null) {
assert(!box.attached);
assert(renderObject._deferredLayoutChild == box);
+ // updateChild has not been called at this point so the RenderTheater in
+ // the overlay location could be detached. Adding children to a detached
+ // RenderObject is still allowed however this isn't the most efficient.
(overlayChild.slot! as _OverlayEntryLocation)._activate(box);
}
}
@@ -1864,12 +1902,8 @@
void deactivate() {
final Element? overlayChild = _overlayChild;
// Instead of just detaching the render objects, removing them from the
- // render subtree entirely such that if the widget gets reparented to a
- // different overlay entry, the overlay child is inserted in the right
- // position in the overlay's child list.
- //
- // This is also a workaround for the !renderObject.attached assert in the
- // `RenderObjectElement.deactive()` method.
+ // render subtree entirely. This is a workaround for the
+ // !renderObject.attached assert in the `super.deactive()` method.
if (overlayChild != null) {
final _RenderDeferredLayoutBox? box = overlayChild.renderObject as _RenderDeferredLayoutBox?;
if (box != null) {
@@ -1894,7 +1928,7 @@
// reparenting between _overlayChild and _child, thus the non-null-typed slots.
@override
void moveRenderObjectChild(_RenderDeferredLayoutBox child, _OverlayEntryLocation oldSlot, _OverlayEntryLocation newSlot) {
- assert(newSlot._debugNotDisposed());
+ assert(newSlot._debugIsLocationValid());
newSlot._moveChild(child, oldSlot);
}
@@ -1980,7 +2014,7 @@
@override
_RenderTheater get theater {
- final AbstractNode? parent = this.parent;
+ final RenderObject? parent = this.parent;
return parent is _RenderTheater
? parent
: throw FlutterError('$parent of $this is not a _RenderTheater');
diff --git a/packages/flutter/lib/src/widgets/platform_view.dart b/packages/flutter/lib/src/widgets/platform_view.dart
index 55653d2..722a22b 100644
--- a/packages/flutter/lib/src/widgets/platform_view.dart
+++ b/packages/flutter/lib/src/widgets/platform_view.dart
@@ -345,7 +345,8 @@
super.key,
required this.viewType,
this.onPlatformViewCreated,
- }) : assert(kIsWeb, 'HtmlElementView is only available on Flutter Web.');
+ this.creationParams,
+ });
/// The unique identifier for the HTML view type to be embedded by this widget.
///
@@ -357,8 +358,12 @@
/// May be null.
final PlatformViewCreatedCallback? onPlatformViewCreated;
+ /// Passed as the 2nd argument (i.e. `params`) of the registered view factory.
+ final Object? creationParams;
+
@override
Widget build(BuildContext context) {
+ assert(kIsWeb, 'HtmlElementView is only available on Flutter Web.');
return PlatformViewLink(
viewType: viewType,
onCreatePlatformView: _createHtmlElementView,
@@ -374,7 +379,11 @@
/// Creates the controller and kicks off its initialization.
_HtmlElementViewController _createHtmlElementView(PlatformViewCreationParams params) {
- final _HtmlElementViewController controller = _HtmlElementViewController(params.id, viewType);
+ final _HtmlElementViewController controller = _HtmlElementViewController(
+ params.id,
+ viewType,
+ creationParams,
+ );
controller._initialize().then((_) {
params.onPlatformViewCreated(params.id);
onPlatformViewCreated?.call(params.id);
@@ -387,6 +396,7 @@
_HtmlElementViewController(
this.viewId,
this.viewType,
+ this.creationParams,
);
@override
@@ -397,12 +407,15 @@
/// A PlatformViewFactory for this type must have been registered.
final String viewType;
+ final dynamic creationParams;
+
bool _initialized = false;
Future<void> _initialize() async {
final Map<String, dynamic> args = <String, dynamic>{
'id': viewId,
'viewType': viewType,
+ 'params': creationParams,
};
await SystemChannels.platform_views.invokeMethod<void>('create', args);
_initialized = true;
diff --git a/packages/flutter/lib/src/widgets/preferred_size.dart b/packages/flutter/lib/src/widgets/preferred_size.dart
index 6714339..899fca2 100644
--- a/packages/flutter/lib/src/widgets/preferred_size.dart
+++ b/packages/flutter/lib/src/widgets/preferred_size.dart
@@ -69,8 +69,8 @@
/// Creates a widget that has a preferred size that the parent can query.
const PreferredSize({
super.key,
- required this.child,
required this.preferredSize,
+ required this.child,
});
/// The widget below this widget in the tree.
diff --git a/packages/flutter/lib/src/widgets/routes.dart b/packages/flutter/lib/src/widgets/routes.dart
index 6c3ddf8..ad919c9 100644
--- a/packages/flutter/lib/src/widgets/routes.dart
+++ b/packages/flutter/lib/src/widgets/routes.dart
@@ -1813,9 +1813,9 @@
///
/// ## Type arguments
///
-/// When using more aggressive
-/// [lints](http://dart-lang.github.io/linter/lints/), in particular lints such
-/// as `always_specify_types`, the Dart analyzer will require that certain types
+/// When using more aggressive [lints](https://dart.dev/lints),
+/// in particular lints such as `always_specify_types`,
+/// the Dart analyzer will require that certain types
/// be given with their type arguments. Since the [Route] class and its
/// subclasses have a type argument, this includes the arguments passed to this
/// class. Consider using `dynamic` to specify the entire class of routes rather
diff --git a/packages/flutter/lib/src/widgets/scrollable.dart b/packages/flutter/lib/src/widgets/scrollable.dart
index cacc0ec..17a9000 100644
--- a/packages/flutter/lib/src/widgets/scrollable.dart
+++ b/packages/flutter/lib/src/widgets/scrollable.dart
@@ -320,6 +320,10 @@
/// the nearest enclosing [ScrollableState] in that [Axis] is returned, or
/// null if there is none.
///
+ /// This finds the nearest _ancestor_ [Scrollable] of the `context`. This
+ /// means that if the `context` is that of a [Scrollable], it will _not_ find
+ /// _that_ [Scrollable].
+ ///
/// See also:
///
/// * [Scrollable.of], which is similar to this method, but asserts
@@ -359,6 +363,10 @@
/// target [Scrollable] is not the closest instance. When [axis] is provided,
/// the nearest enclosing [ScrollableState] in that [Axis] is returned.
///
+ /// This finds the nearest _ancestor_ [Scrollable] of the `context`. This
+ /// means that if the `context` is that of a [Scrollable], it will _not_ find
+ /// _that_ [Scrollable].
+ ///
/// If no [Scrollable] ancestor is found, then this method will assert in
/// debug mode, and throw an exception in release mode.
///
@@ -943,7 +951,6 @@
Widget result = _ScrollableScope(
scrollable: this,
position: position,
- // TODO(ianh): Having all these global keys is sad.
child: Listener(
onPointerSignal: _receivedPointerSignal,
child: RawGestureDetector(
diff --git a/packages/flutter/lib/src/widgets/scrollable_helpers.dart b/packages/flutter/lib/src/widgets/scrollable_helpers.dart
index 4e50c4a..20466f9 100644
--- a/packages/flutter/lib/src/widgets/scrollable_helpers.dart
+++ b/packages/flutter/lib/src/widgets/scrollable_helpers.dart
@@ -10,7 +10,6 @@
import 'actions.dart';
import 'basic.dart';
-import 'focus_manager.dart';
import 'framework.dart';
import 'primary_scroll_controller.dart';
import 'scroll_configuration.dart';
@@ -377,10 +376,10 @@
final ScrollIncrementType type;
}
-/// An [Action] that scrolls the [Scrollable] that encloses the current
-/// [primaryFocus] by the amount configured in the [ScrollIntent] given to it.
+/// An [Action] that scrolls the relevant [Scrollable] by the amount configured
+/// in the [ScrollIntent] given to it.
///
-/// If a Scrollable cannot be found above the current [primaryFocus], the
+/// If a Scrollable cannot be found above the given [BuildContext], the
/// [PrimaryScrollController] will be considered for default handling of
/// [ScrollAction]s.
///
@@ -388,21 +387,17 @@
/// for a [ScrollIntent.type] set to [ScrollIncrementType.page] is 80% of the
/// size of the scroll window, and for [ScrollIncrementType.line], 50 logical
/// pixels.
-class ScrollAction extends Action<ScrollIntent> {
+class ScrollAction extends ContextAction<ScrollIntent> {
@override
- bool isEnabled(ScrollIntent intent) {
- final FocusNode? focus = primaryFocus;
- final bool contextIsValid = focus != null && focus.context != null;
- if (contextIsValid) {
- // Check for primary scrollable within the current context
- if (Scrollable.maybeOf(focus.context!) != null) {
- return true;
- }
- // Check for fallback scrollable with context from PrimaryScrollController
- final ScrollController? primaryScrollController = PrimaryScrollController.maybeOf(focus.context!);
- return primaryScrollController != null && primaryScrollController.hasClients;
+ bool isEnabled(ScrollIntent intent, [BuildContext? context]) {
+ if (context == null) {
+ return false;
}
- return false;
+ if (Scrollable.maybeOf(context) != null) {
+ return true;
+ }
+ final ScrollController? primaryScrollController = PrimaryScrollController.maybeOf(context);
+ return (primaryScrollController != null) && (primaryScrollController.hasClients);
}
/// Returns the scroll increment for a single scroll request, for use when
@@ -480,10 +475,11 @@
}
@override
- void invoke(ScrollIntent intent) {
- ScrollableState? state = Scrollable.maybeOf(primaryFocus!.context!);
+ void invoke(ScrollIntent intent, [BuildContext? context]) {
+ assert(context != null, 'Cannot scroll without a context.');
+ ScrollableState? state = Scrollable.maybeOf(context!);
if (state == null) {
- final ScrollController primaryScrollController = PrimaryScrollController.of(primaryFocus!.context!);
+ final ScrollController primaryScrollController = PrimaryScrollController.of(context);
assert (() {
if (primaryScrollController.positions.length != 1) {
throw FlutterError.fromParts(<DiagnosticsNode>[
diff --git a/packages/flutter/lib/src/widgets/selectable_region.dart b/packages/flutter/lib/src/widgets/selectable_region.dart
index 290f526..568cb64 100644
--- a/packages/flutter/lib/src/widgets/selectable_region.dart
+++ b/packages/flutter/lib/src/widgets/selectable_region.dart
@@ -39,6 +39,11 @@
PointerDeviceKind.invertedStylus,
};
+// In practice some selectables like widgetspan shift several pixels. So when
+// the vertical position diff is within the threshold, compare the horizontal
+// position to make the compareScreenOrder function more robust.
+const double _kSelectableVerticalComparingThreshold = 3.0;
+
/// A widget that introduces an area for user selections.
///
/// Flutter widgets are not selectable by default. Wrapping a widget subtree
@@ -263,7 +268,7 @@
required final VoidCallback onCopy,
required final VoidCallback onSelectAll,
}) {
- final bool canCopy = selectionGeometry.hasSelection;
+ final bool canCopy = selectionGeometry.status == SelectionStatus.uncollapsed;
final bool canSelectAll = selectionGeometry.hasContent;
// Determine which buttons will appear so that the order and total number is
@@ -439,8 +444,7 @@
instance
..onLongPressStart = _handleTouchLongPressStart
..onLongPressMoveUpdate = _handleTouchLongPressMoveUpdate
- ..onLongPressEnd = _handleTouchLongPressEnd
- ..onLongPressCancel = _clearSelection;
+ ..onLongPressEnd = _handleTouchLongPressEnd;
},
);
}
@@ -489,12 +493,62 @@
_updateSelectedContentIfNeeded();
}
+ bool _positionIsOnActiveSelection({required Offset globalPosition}) {
+ for (final Rect selectionRect in _selectionDelegate.value.selectionRects) {
+ final Matrix4 transform = _selectable!.getTransformTo(null);
+ final Rect globalRect = MatrixUtils.transformRect(transform, selectionRect);
+ if (globalRect.contains(globalPosition)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
void _handleRightClickDown(TapDownDetails details) {
+ final Offset? previousSecondaryTapDownPosition = lastSecondaryTapDownPosition;
+ final bool toolbarIsVisible = _selectionOverlay?.toolbarIsVisible ?? false;
lastSecondaryTapDownPosition = details.globalPosition;
widget.focusNode.requestFocus();
- _selectWordAt(offset: details.globalPosition);
- _showHandles();
- _showToolbar(location: details.globalPosition);
+ switch (defaultTargetPlatform) {
+ case TargetPlatform.android:
+ case TargetPlatform.fuchsia:
+ case TargetPlatform.windows:
+ // If lastSecondaryTapDownPosition is within the current selection then
+ // keep the current selection, if not then collapse it.
+ final bool lastSecondaryTapDownPositionWasOnActiveSelection = _positionIsOnActiveSelection(globalPosition: details.globalPosition);
+ if (!lastSecondaryTapDownPositionWasOnActiveSelection) {
+ _selectStartTo(offset: lastSecondaryTapDownPosition!);
+ _selectEndTo(offset: lastSecondaryTapDownPosition!);
+ }
+ _showHandles();
+ _showToolbar(location: lastSecondaryTapDownPosition);
+ case TargetPlatform.iOS:
+ _selectWordAt(offset: lastSecondaryTapDownPosition!);
+ _showHandles();
+ _showToolbar(location: lastSecondaryTapDownPosition);
+ case TargetPlatform.macOS:
+ if (previousSecondaryTapDownPosition == lastSecondaryTapDownPosition && toolbarIsVisible) {
+ hideToolbar();
+ return;
+ }
+ _selectWordAt(offset: lastSecondaryTapDownPosition!);
+ _showHandles();
+ _showToolbar(location: lastSecondaryTapDownPosition);
+ case TargetPlatform.linux:
+ if (toolbarIsVisible) {
+ hideToolbar();
+ return;
+ }
+ // If lastSecondaryTapDownPosition is within the current selection then
+ // keep the current selection, if not then collapse it.
+ final bool lastSecondaryTapDownPositionWasOnActiveSelection = _positionIsOnActiveSelection(globalPosition: details.globalPosition);
+ if (!lastSecondaryTapDownPositionWasOnActiveSelection) {
+ _selectStartTo(offset: lastSecondaryTapDownPosition!);
+ _selectEndTo(offset: lastSecondaryTapDownPosition!);
+ }
+ _showHandles();
+ _showToolbar(location: lastSecondaryTapDownPosition);
+ }
_updateSelectedContentIfNeeded();
}
@@ -1654,11 +1708,11 @@
/// Returns positive if a is lower, negative if a is higher, 0 if their
/// order can't be determine solely by their vertical position.
static int _compareVertically(Rect a, Rect b) {
- if ((a.top - b.top < precisionErrorTolerance && a.bottom - b.bottom > - precisionErrorTolerance) ||
- (b.top - a.top < precisionErrorTolerance && b.bottom - a.bottom > - precisionErrorTolerance)) {
+ if ((a.top - b.top < _kSelectableVerticalComparingThreshold && a.bottom - b.bottom > - _kSelectableVerticalComparingThreshold) ||
+ (b.top - a.top < _kSelectableVerticalComparingThreshold && b.bottom - a.bottom > - _kSelectableVerticalComparingThreshold)) {
return 0;
}
- if ((a.top - b.top).abs() > precisionErrorTolerance) {
+ if ((a.top - b.top).abs() > _kSelectableVerticalComparingThreshold) {
return a.top > b.top ? 1 : -1;
}
return a.bottom > b.bottom ? 1 : -1;
@@ -1770,9 +1824,30 @@
}
}
+ // Need to collect selection rects from selectables ranging from the
+ // currentSelectionStartIndex to the currentSelectionEndIndex.
+ final List<Rect> selectionRects = <Rect>[];
+ final Rect? drawableArea = hasSize ? Rect
+ .fromLTWH(0, 0, containerSize.width, containerSize.height) : null;
+ for (int index = currentSelectionStartIndex; index <= currentSelectionEndIndex; index++) {
+ final List<Rect> currSelectableSelectionRects = selectables[index].value.selectionRects;
+ final List<Rect> selectionRectsWithinDrawableArea = currSelectableSelectionRects.map((Rect selectionRect) {
+ final Matrix4 transform = getTransformFrom(selectables[index]);
+ final Rect localRect = MatrixUtils.transformRect(transform, selectionRect);
+ if (drawableArea != null) {
+ return drawableArea.intersect(localRect);
+ }
+ return localRect;
+ }).where((Rect selectionRect) {
+ return selectionRect.isFinite && !selectionRect.isEmpty;
+ }).toList();
+ selectionRects.addAll(selectionRectsWithinDrawableArea);
+ }
+
return SelectionGeometry(
startSelectionPoint: startPoint,
endSelectionPoint: endPoint,
+ selectionRects: selectionRects,
status: startGeometry != endGeometry
? SelectionStatus.uncollapsed
: startGeometry.status,
diff --git a/packages/flutter/lib/src/widgets/shortcuts.dart b/packages/flutter/lib/src/widgets/shortcuts.dart
index 6ec98f3..5bc3879 100644
--- a/packages/flutter/lib/src/widgets/shortcuts.dart
+++ b/packages/flutter/lib/src/widgets/shortcuts.dart
@@ -843,9 +843,13 @@
primaryContext,
intent: matchedIntent,
);
- if (action != null && action.isEnabled(matchedIntent)) {
- final Object? invokeResult = Actions.of(primaryContext).invokeAction(action, matchedIntent, primaryContext);
- return action.toKeyEventResult(matchedIntent, invokeResult);
+ if (action != null) {
+ final (bool enabled, Object? invokeResult) = Actions.of(primaryContext).invokeActionIfEnabled(
+ action, matchedIntent, primaryContext,
+ );
+ if (enabled) {
+ return action.toKeyEventResult(matchedIntent, invokeResult);
+ }
}
}
}
@@ -1047,6 +1051,8 @@
/// A widget that binds key combinations to specific callbacks.
///
+/// {@youtube 560 315 https://www.youtube.com/watch?v=VcQQ1ns_qNY}
+///
/// This is similar to but simpler than the [Shortcuts] widget as it doesn't
/// require [Intent]s and [Actions] widgets. Instead, it accepts a map
/// of [ShortcutActivator]s to [VoidCallback]s.
diff --git a/packages/flutter/lib/src/widgets/sliver.dart b/packages/flutter/lib/src/widgets/sliver.dart
index 46b42cf..0090198 100644
--- a/packages/flutter/lib/src/widgets/sliver.dart
+++ b/packages/flutter/lib/src/widgets/sliver.dart
@@ -1342,7 +1342,7 @@
if (parentData.keepAlive != keepAlive) {
// No need to redo layout if it became true.
parentData.keepAlive = keepAlive;
- final AbstractNode? targetParent = renderObject.parent;
+ final RenderObject? targetParent = renderObject.parent;
if (targetParent is RenderObject && !keepAlive) {
targetParent.markNeedsLayout();
}
@@ -1436,7 +1436,7 @@
}
if (needsLayout) {
- final AbstractNode? targetParent = renderObject.parent;
+ final RenderObject? targetParent = renderObject.parent;
if (targetParent is RenderObject) {
targetParent.markNeedsLayout();
}
@@ -1508,7 +1508,7 @@
}
if (needsLayout) {
- final AbstractNode? targetParent = renderObject.parent;
+ final RenderObject? targetParent = renderObject.parent;
if (targetParent is RenderObject) {
targetParent.markNeedsLayout();
}
diff --git a/packages/flutter/lib/src/widgets/table.dart b/packages/flutter/lib/src/widgets/table.dart
index 83d54be..a3aba1c 100644
--- a/packages/flutter/lib/src/widgets/table.dart
+++ b/packages/flutter/lib/src/widgets/table.dart
@@ -417,7 +417,7 @@
final TableCellParentData parentData = renderObject.parentData! as TableCellParentData;
if (parentData.verticalAlignment != verticalAlignment) {
parentData.verticalAlignment = verticalAlignment;
- final AbstractNode? targetParent = renderObject.parent;
+ final RenderObject? targetParent = renderObject.parent;
if (targetParent is RenderObject) {
targetParent.markNeedsLayout();
}
diff --git a/packages/flutter/lib/src/widgets/tap_and_drag_gestures.dart b/packages/flutter/lib/src/widgets/tap_and_drag_gestures.dart
index 4bf60f9..51a8435 100644
--- a/packages/flutter/lib/src/widgets/tap_and_drag_gestures.dart
+++ b/packages/flutter/lib/src/widgets/tap_and_drag_gestures.dart
@@ -539,6 +539,9 @@
@override
void addAllowedPointer(PointerDownEvent event) {
super.addAllowedPointer(event);
+ if (_consecutiveTapTimer != null && !_consecutiveTapTimer!.isActive) {
+ _tapTrackerReset();
+ }
if (maxConsecutiveTap == _consecutiveTapCount) {
_tapTrackerReset();
}
@@ -623,7 +626,7 @@
}
void _consecutiveTapTimerStart() {
- _consecutiveTapTimer ??= Timer(kDoubleTapTimeout, _tapTrackerReset);
+ _consecutiveTapTimer ??= Timer(kDoubleTapTimeout, _consecutiveTapTimerTimeout);
}
void _consecutiveTapTimerStop() {
@@ -633,6 +636,13 @@
}
}
+ void _consecutiveTapTimerTimeout() {
+ // The consecutive tap timer may time out before a tap down/tap up event is
+ // fired. In this case we should not reset the tap tracker state immediately.
+ // Instead we should reset the tap tracker on the next call to [addAllowedPointer],
+ // if the timer is no longer active.
+ }
+
void _tapTrackerReset() {
// The timer has timed out, i.e. the time between a [PointerUpEvent] and the subsequent
// [PointerDownEvent] exceeded the duration of [kDoubleTapTimeout], so the tap belonging
diff --git a/packages/flutter/lib/src/widgets/text_selection.dart b/packages/flutter/lib/src/widgets/text_selection.dart
index 33d0e9b..a447e6e 100644
--- a/packages/flutter/lib/src/widgets/text_selection.dart
+++ b/packages/flutter/lib/src/widgets/text_selection.dart
@@ -562,15 +562,13 @@
/// Whether the handles are currently visible.
bool get handlesAreVisible => _selectionOverlay._handles != null && handlesVisible;
- /// Whether the toolbar is currently visible.
- ///
- /// Includes both the text selection toolbar and the spell check menu.
+ /// {@macro flutter.widgets.SelectionOverlay.toolbarIsVisible}
///
/// See also:
///
/// * [spellCheckToolbarIsVisible], which is only whether the spell check menu
/// specifically is visible.
- bool get toolbarIsVisible => _selectionOverlay._toolbarIsVisible;
+ bool get toolbarIsVisible => _selectionOverlay.toolbarIsVisible;
/// Whether the magnifier is currently visible.
bool get magnifierIsVisible => _selectionOverlay._magnifierController.shown;
@@ -984,7 +982,12 @@
/// {@macro flutter.widgets.magnifier.TextMagnifierConfiguration.details}
final TextMagnifierConfiguration magnifierConfiguration;
- bool get _toolbarIsVisible {
+ /// {@template flutter.widgets.SelectionOverlay.toolbarIsVisible}
+ /// Whether the toolbar is currently visible.
+ ///
+ /// Includes both the text selection toolbar and the spell check menu.
+ /// {@endtemplate}
+ bool get toolbarIsVisible {
return selectionControls is TextSelectionHandleControls
? _contextMenuController.isShown || _spellCheckToolbarController.isShown
: _toolbar != null || _spellCheckToolbarController.isShown;
@@ -1001,7 +1004,7 @@
/// [MagnifierController.shown].
/// {@endtemplate}
void showMagnifier(MagnifierInfo initialMagnifierInfo) {
- if (_toolbarIsVisible) {
+ if (toolbarIsVisible) {
hideToolbar();
}
@@ -1088,10 +1091,26 @@
void _handleStartHandleDragStart(DragStartDetails details) {
assert(!_isDraggingStartHandle);
+ // Calling OverlayEntry.remove may not happen until the following frame, so
+ // it's possible for the handles to receive a gesture after calling remove.
+ if (_handles == null) {
+ _isDraggingStartHandle = false;
+ return;
+ }
_isDraggingStartHandle = details.kind == PointerDeviceKind.touch;
onStartHandleDragStart?.call(details);
}
+ void _handleStartHandleDragUpdate(DragUpdateDetails details) {
+ // Calling OverlayEntry.remove may not happen until the following frame, so
+ // it's possible for the handles to receive a gesture after calling remove.
+ if (_handles == null) {
+ _isDraggingStartHandle = false;
+ return;
+ }
+ onStartHandleDragUpdate?.call(details);
+ }
+
/// Called when the users drag the start selection handles to new locations.
final ValueChanged<DragUpdateDetails>? onStartHandleDragUpdate;
@@ -1101,6 +1120,11 @@
void _handleStartHandleDragEnd(DragEndDetails details) {
_isDraggingStartHandle = false;
+ // Calling OverlayEntry.remove may not happen until the following frame, so
+ // it's possible for the handles to receive a gesture after calling remove.
+ if (_handles == null) {
+ return;
+ }
onStartHandleDragEnd?.call(details);
}
@@ -1147,10 +1171,26 @@
void _handleEndHandleDragStart(DragStartDetails details) {
assert(!_isDraggingEndHandle);
+ // Calling OverlayEntry.remove may not happen until the following frame, so
+ // it's possible for the handles to receive a gesture after calling remove.
+ if (_handles == null) {
+ _isDraggingEndHandle = false;
+ return;
+ }
_isDraggingEndHandle = details.kind == PointerDeviceKind.touch;
onEndHandleDragStart?.call(details);
}
+ void _handleEndHandleDragUpdate(DragUpdateDetails details) {
+ // Calling OverlayEntry.remove may not happen until the following frame, so
+ // it's possible for the handles to receive a gesture after calling remove.
+ if (_handles == null) {
+ _isDraggingEndHandle = false;
+ return;
+ }
+ onEndHandleDragUpdate?.call(details);
+ }
+
/// Called when the users drag the end selection handles to new locations.
final ValueChanged<DragUpdateDetails>? onEndHandleDragUpdate;
@@ -1160,6 +1200,11 @@
void _handleEndHandleDragEnd(DragEndDetails details) {
_isDraggingEndHandle = false;
+ // Calling OverlayEntry.remove may not happen until the following frame, so
+ // it's possible for the handles to receive a gesture after calling remove.
+ if (_handles == null) {
+ return;
+ }
onEndHandleDragEnd?.call(details);
}
@@ -1472,7 +1517,7 @@
handleLayerLink: startHandleLayerLink,
onSelectionHandleTapped: onSelectionHandleTapped,
onSelectionHandleDragStart: _handleStartHandleDragStart,
- onSelectionHandleDragUpdate: onStartHandleDragUpdate,
+ onSelectionHandleDragUpdate: _handleStartHandleDragUpdate,
onSelectionHandleDragEnd: _handleStartHandleDragEnd,
selectionControls: selectionControls,
visibility: startHandlesVisible,
@@ -1499,7 +1544,7 @@
handleLayerLink: endHandleLayerLink,
onSelectionHandleTapped: onSelectionHandleTapped,
onSelectionHandleDragStart: _handleEndHandleDragStart,
- onSelectionHandleDragUpdate: onEndHandleDragUpdate,
+ onSelectionHandleDragUpdate: _handleEndHandleDragUpdate,
onSelectionHandleDragEnd: _handleEndHandleDragEnd,
selectionControls: selectionControls,
visibility: endHandlesVisible,
@@ -1752,7 +1797,7 @@
// Make sure the GestureDetector is big enough to be easily interactive.
final Rect interactiveRect = handleRect.expandToInclude(
- Rect.fromCircle(center: handleRect.center, radius: kMinInteractiveDimension/ 2),
+ Rect.fromCircle(center: handleRect.center, radius: kMinInteractiveDimension / 2),
);
final RelativeRect padding = RelativeRect.fromLTRB(
math.max((interactiveRect.width - handleRect.width) / 2, 0),
@@ -3267,7 +3312,7 @@
));
// In the case of an error from the Clipboard API, set the value to
// unknown so that it will try to update again later.
- if (_disposed || value == ClipboardStatus.unknown) {
+ if (_disposed) {
return;
}
value = ClipboardStatus.unknown;
@@ -3277,7 +3322,7 @@
? ClipboardStatus.pasteable
: ClipboardStatus.notPasteable;
- if (_disposed || nextStatus == value) {
+ if (_disposed) {
return;
}
value = nextStatus;
@@ -3338,6 +3383,115 @@
notPasteable,
}
+/// A [ValueNotifier] whose [value] indicates whether the current device supports the Live Text
+/// (OCR) function.
+///
+/// See also:
+/// * [LiveText], where the availability of Live Text input can be obtained.
+/// * [LiveTextInputStatus], an enumeration that indicates whether the current device is available
+/// for Live Text input.
+///
+/// Call [update] to asynchronously update [value] if needed.
+class LiveTextInputStatusNotifier extends ValueNotifier<LiveTextInputStatus> with WidgetsBindingObserver {
+ /// Create a new LiveTextStatusNotifier.
+ LiveTextInputStatusNotifier({
+ LiveTextInputStatus value = LiveTextInputStatus.unknown,
+ }) : super(value);
+
+ bool _disposed = false;
+
+ /// Check the [LiveTextInputStatus] and update [value] if needed.
+ Future<void> update() async {
+ if (_disposed) {
+ return;
+ }
+
+ final bool isLiveTextInputEnabled;
+ try {
+ isLiveTextInputEnabled = await LiveText.isLiveTextInputAvailable();
+ } catch (exception, stack) {
+ FlutterError.reportError(FlutterErrorDetails(
+ exception: exception,
+ stack: stack,
+ library: 'widget library',
+ context: ErrorDescription('while checking the availability of Live Text input'),
+ ));
+ // In the case of an error from the Live Text API, set the value to
+ // unknown so that it will try to update again later.
+ if (_disposed || value == LiveTextInputStatus.unknown) {
+ return;
+ }
+ value = LiveTextInputStatus.unknown;
+ return;
+ }
+
+ final LiveTextInputStatus nextStatus = isLiveTextInputEnabled
+ ? LiveTextInputStatus.enabled
+ : LiveTextInputStatus.disabled;
+
+ if (_disposed || nextStatus == value) {
+ return;
+ }
+ value = nextStatus;
+ }
+
+ @override
+ void addListener(VoidCallback listener) {
+ if (!hasListeners) {
+ WidgetsBinding.instance.addObserver(this);
+ }
+ if (value == LiveTextInputStatus.unknown) {
+ update();
+ }
+ super.addListener(listener);
+ }
+
+ @override
+ void removeListener(VoidCallback listener) {
+ super.removeListener(listener);
+ if (!_disposed && !hasListeners) {
+ WidgetsBinding.instance.removeObserver(this);
+ }
+ }
+
+ @override
+ void didChangeAppLifecycleState(AppLifecycleState state) {
+ switch (state) {
+ case AppLifecycleState.resumed:
+ update();
+ case AppLifecycleState.detached:
+ case AppLifecycleState.inactive:
+ case AppLifecycleState.paused:
+ case AppLifecycleState.hidden:
+ // Nothing to do.
+ }
+ }
+
+ @override
+ void dispose() {
+ WidgetsBinding.instance.removeObserver(this);
+ _disposed = true;
+ super.dispose();
+ }
+}
+
+/// An enumeration that indicates whether the current device is available for Live Text input.
+///
+/// See also:
+/// * [LiveText], where the availability of Live Text input can be obtained.
+enum LiveTextInputStatus {
+ /// This device supports Live Text input currently.
+ enabled,
+
+ /// The status of the Live Text input is unknown. Since getting the Live Text input availability
+ /// is asynchronous (see [LiveText.isLiveTextInputAvailable]), this status often exists while
+ /// waiting to receive the status value for the first time.
+ unknown,
+
+ /// The current device doesn't support Live Text input.
+ disabled,
+}
+
// TODO(justinmc): Deprecate this after TextSelectionControls.buildToolbar is
// deleted, when users should migrate back to TextSelectionControls.buildHandle.
// See https://github.com/flutter/flutter/pull/124262
diff --git a/packages/flutter/lib/src/widgets/widget_inspector.dart b/packages/flutter/lib/src/widgets/widget_inspector.dart
index 34ad78b..7a88e92 100644
--- a/packages/flutter/lib/src/widgets/widget_inspector.dart
+++ b/packages/flutter/lib/src/widgets/widget_inspector.dart
@@ -553,7 +553,7 @@
}) {
RenderObject repaintBoundary = renderObject;
while (!repaintBoundary.isRepaintBoundary) {
- repaintBoundary = repaintBoundary.parent! as RenderObject;
+ repaintBoundary = repaintBoundary.parent!;
}
final _ScreenshotData data = _ScreenshotData(target: renderObject);
final _ScreenshotPaintingContext context = _ScreenshotPaintingContext(
@@ -680,11 +680,39 @@
/// Structure to help reference count Dart objects referenced by a GUI tool
/// using [WidgetInspectorService].
-class _InspectorReferenceData {
- _InspectorReferenceData(this.object);
+///
+/// Does not hold the object from garbage collection.
+@visibleForTesting
+class InspectorReferenceData {
+ /// Creates an instance of [InspectorReferenceData].
+ InspectorReferenceData(Object object, this.id) {
+ // These types are not supported by [WeakReference].
+ // See https://api.dart.dev/stable/3.0.2/dart-core/WeakReference-class.html
+ if (object is String || object is num || object is bool) {
+ _value = object;
+ return;
+ }
- final Object object;
+ _ref = WeakReference<Object>(object);
+ }
+
+ WeakReference<Object>? _ref;
+
+ Object? _value;
+
+ /// The id of the object in the widget inspector records.
+ final String id;
+
+ /// The number of times the object has been referenced.
int count = 1;
+
+ /// The value.
+ Object? get value {
+ if (_ref != null) {
+ return _ref!.target;
+ }
+ return _value;
+ }
}
// Production implementation of [WidgetInspectorService].
@@ -742,9 +770,9 @@
/// The VM service protocol does not keep alive object references so this
/// class needs to manually manage groups of objects that should be kept
/// alive.
- final Map<String, Set<_InspectorReferenceData>> _groups = <String, Set<_InspectorReferenceData>>{};
- final Map<String, _InspectorReferenceData> _idToReferenceData = <String, _InspectorReferenceData>{};
- final Map<Object, String> _objectToId = Map<Object, String>.identity();
+ final Map<String, Set<InspectorReferenceData>> _groups = <String, Set<InspectorReferenceData>>{};
+ final Map<String, InspectorReferenceData> _idToReferenceData = <String, InspectorReferenceData>{};
+ final WeakMap<Object, String> _objectToId = WeakMap<Object, String>();
int _nextId = 0;
/// The pubRootDirectories that are currently configured for the widget inspector.
@@ -1270,20 +1298,22 @@
/// references from a different group.
@protected
void disposeGroup(String name) {
- final Set<_InspectorReferenceData>? references = _groups.remove(name);
+ final Set<InspectorReferenceData>? references = _groups.remove(name);
if (references == null) {
return;
}
references.forEach(_decrementReferenceCount);
}
- void _decrementReferenceCount(_InspectorReferenceData reference) {
+ void _decrementReferenceCount(InspectorReferenceData reference) {
reference.count -= 1;
assert(reference.count >= 0);
if (reference.count == 0) {
- final String? id = _objectToId.remove(reference.object);
- assert(id != null);
- _idToReferenceData.remove(id);
+ final Object? value = reference.value;
+ if (value != null) {
+ _objectToId.remove(value);
+ }
+ _idToReferenceData.remove(reference.id);
}
}
@@ -1295,14 +1325,16 @@
return null;
}
- final Set<_InspectorReferenceData> group = _groups.putIfAbsent(groupName, () => Set<_InspectorReferenceData>.identity());
+ final Set<InspectorReferenceData> group = _groups.putIfAbsent(groupName, () => Set<InspectorReferenceData>.identity());
String? id = _objectToId[object];
- _InspectorReferenceData referenceData;
+ InspectorReferenceData referenceData;
if (id == null) {
+ // TODO(polina-c): comment here why we increase memory footprint by the prefix 'inspector-'.
+ // https://github.com/flutter/devtools/issues/5995
id = 'inspector-$_nextId';
_nextId += 1;
_objectToId[object] = id;
- referenceData = _InspectorReferenceData(object);
+ referenceData = InspectorReferenceData(object, id);
_idToReferenceData[id] = referenceData;
group.add(referenceData);
} else {
@@ -1332,11 +1364,11 @@
return null;
}
- final _InspectorReferenceData? data = _idToReferenceData[id];
+ final InspectorReferenceData? data = _idToReferenceData[id];
if (data == null) {
throw FlutterError.fromParts(<DiagnosticsNode>[ErrorSummary('Id does not exist.')]);
}
- return data.object;
+ return data.value;
}
/// Returns the object to introspect to determine the source location of an
@@ -1368,7 +1400,7 @@
return;
}
- final _InspectorReferenceData? referenceData = _idToReferenceData[id];
+ final InspectorReferenceData? referenceData = _idToReferenceData[id];
if (referenceData == null) {
throw FlutterError.fromParts(<DiagnosticsNode>[ErrorSummary('Id does not exist')]);
}
@@ -1632,7 +1664,7 @@
final List<RenderObject> chain = <RenderObject>[];
while (renderObject != null) {
chain.add(renderObject);
- renderObject = renderObject.parent as RenderObject?;
+ renderObject = renderObject.parent;
}
return _followDiagnosticableChain(chain.reversed.toList());
}
@@ -1722,9 +1754,12 @@
return _safeJsonEncode(_getProperties(diagnosticsNodeId, groupName));
}
- List<Object> _getProperties(String? diagnosticsNodeId, String groupName) {
- final DiagnosticsNode? node = toObject(diagnosticsNodeId) as DiagnosticsNode?;
- return _nodesToJson(node == null ? const <DiagnosticsNode>[] : node.getProperties(), InspectorSerializationDelegate(groupName: groupName, service: this), parent: node);
+ List<Object> _getProperties(String? diagnosticableId, String groupName) {
+ final DiagnosticsNode? node = _idToDiagnosticsNode(diagnosticableId);
+ if (node == null) {
+ return const <Object>[];
+ }
+ return _nodesToJson(node.getProperties(), InspectorSerializationDelegate(groupName: groupName, service: this), parent: node);
}
/// Returns a JSON representation of the children of the [DiagnosticsNode]
@@ -1757,24 +1792,42 @@
return _safeJsonEncode(_getChildrenSummaryTree(diagnosticsNodeId, groupName));
}
- List<Object> _getChildrenSummaryTree(String? diagnosticsNodeId, String groupName) {
- final DiagnosticsNode? node = toObject(diagnosticsNodeId) as DiagnosticsNode?;
+ DiagnosticsNode? _idToDiagnosticsNode(String? diagnosticableId) {
+ final Object? object = toObject(diagnosticableId);
+ return objectToDiagnosticsNode(object);
+ }
+
+ /// If possible, returns [DiagnosticsNode] for the object.
+ @visibleForTesting
+ static DiagnosticsNode? objectToDiagnosticsNode(Object? object) {
+ if (object is Diagnosticable) {
+ return object.toDiagnosticsNode();
+ }
+ return null;
+ }
+
+ List<Object> _getChildrenSummaryTree(String? diagnosticableId, String groupName) {
+ final DiagnosticsNode? node = _idToDiagnosticsNode(diagnosticableId);
+ if (node == null) {
+ return <Object>[];
+ }
+
final InspectorSerializationDelegate delegate = InspectorSerializationDelegate(groupName: groupName, summaryTree: true, service: this);
- return _nodesToJson(node == null ? const <DiagnosticsNode>[] : _getChildrenFiltered(node, delegate), delegate, parent: node);
+ return _nodesToJson(_getChildrenFiltered(node, delegate), delegate, parent: node);
}
/// Returns a JSON representation of the children of the [DiagnosticsNode]
- /// object that `diagnosticsNodeId` references providing information needed
+ /// object that [diagnosticableId] references providing information needed
/// for the details subtree view.
///
/// The details subtree shows properties inline and includes all children
/// rather than a filtered set of important children.
- String getChildrenDetailsSubtree(String diagnosticsNodeId, String groupName) {
- return _safeJsonEncode(_getChildrenDetailsSubtree(diagnosticsNodeId, groupName));
+ String getChildrenDetailsSubtree(String diagnosticableId, String groupName) {
+ return _safeJsonEncode(_getChildrenDetailsSubtree(diagnosticableId, groupName));
}
- List<Object> _getChildrenDetailsSubtree(String? diagnosticsNodeId, String groupName) {
- final DiagnosticsNode? node = toObject(diagnosticsNodeId) as DiagnosticsNode?;
+ List<Object> _getChildrenDetailsSubtree(String? diagnosticableId, String groupName) {
+ final DiagnosticsNode? node = _idToDiagnosticsNode(diagnosticableId);
// With this value of minDepth we only expand one extra level of important nodes.
final InspectorSerializationDelegate delegate = InspectorSerializationDelegate(groupName: groupName, includeProperties: true, service: this);
return _nodesToJson(node == null ? const <DiagnosticsNode>[] : _getChildrenFiltered(node, delegate), delegate, parent: node);
@@ -1886,19 +1939,19 @@
/// * [getChildrenDetailsSubtree], a method to get children of a node
/// in the details subtree.
String getDetailsSubtree(
- String id,
+ String diagnosticableId,
String groupName, {
int subtreeDepth = 2,
}) {
- return _safeJsonEncode(_getDetailsSubtree( id, groupName, subtreeDepth));
+ return _safeJsonEncode(_getDetailsSubtree(diagnosticableId, groupName, subtreeDepth));
}
Map<String, Object?>? _getDetailsSubtree(
- String? id,
+ String? diagnosticableId,
String? groupName,
int subtreeDepth,
) {
- final DiagnosticsNode? root = toObject(id) as DiagnosticsNode?;
+ final DiagnosticsNode? root = _idToDiagnosticsNode(diagnosticableId);
if (root == null) {
return null;
}
@@ -1914,13 +1967,12 @@
}
/// Returns a [DiagnosticsNode] representing the currently selected [Element].
- ///
- /// If the currently selected [Element] is identical to the [Element]
- /// referenced by `previousSelectionId` then the previous [DiagnosticsNode] is
- /// reused.
@protected
String getSelectedWidget(String? previousSelectionId, String groupName) {
- return _safeJsonEncode(_getSelectedWidget(previousSelectionId, groupName));
+ if (previousSelectionId != null) {
+ debugPrint('previousSelectionId is deprecated in API');
+ }
+ return _safeJsonEncode(_getSelectedWidget(null, groupName));
}
/// Captures an image of the current state of an [object] that is a
@@ -1996,18 +2048,18 @@
Future<Map<String, Object?>> _getLayoutExplorerNode(
Map<String, String> parameters,
) {
- final String? id = parameters['id'];
+ final String? diagnosticableId = parameters['id'];
final int subtreeDepth = int.parse(parameters['subtreeDepth']!);
final String? groupName = parameters['groupName'];
Map<String, dynamic>? result = <String, dynamic>{};
- final Object? root = toObject(id);
+ final DiagnosticsNode? root = _idToDiagnosticsNode(diagnosticableId);
if (root == null) {
return Future<Map<String, dynamic>>.value(<String, dynamic>{
'result': result,
});
}
result = _nodeToJson(
- root as DiagnosticsNode,
+ root,
InspectorSerializationDelegate(
groupName: groupName,
summaryTree: true,
@@ -2029,7 +2081,7 @@
'renderObject': renderObject.toDiagnosticsNode().toJsonMap(renderObjectSerializationDelegate),
};
- final AbstractNode? renderParent = renderObject.parent;
+ final RenderObject? renderParent = renderObject.parent;
if (renderParent is RenderObject && subtreeDepth > 0) {
final Object? parentCreator = renderParent.debugCreator;
if (parentCreator is DebugCreator) {
@@ -2204,12 +2256,11 @@
/// if the selected [Element] should be shown in the summary tree otherwise
/// returns the first ancestor of the selected [Element] shown in the summary
/// tree.
- ///
- /// If the currently selected [Element] is identical to the [Element]
- /// referenced by `previousSelectionId` then the previous [DiagnosticsNode] is
- /// reused.
- String getSelectedSummaryWidget(String previousSelectionId, String groupName) {
- return _safeJsonEncode(_getSelectedSummaryWidget(previousSelectionId, groupName));
+ String getSelectedSummaryWidget(String? previousSelectionId, String groupName) {
+ if (previousSelectionId != null) {
+ debugPrint('previousSelectionId is deprecated in API');
+ }
+ return _safeJsonEncode(_getSelectedSummaryWidget(null, groupName));
}
_Location? _getSelectedSummaryWidgetLocation(String? previousSelectionId) {
@@ -2924,7 +2975,7 @@
context.addLayer(_InspectorOverlayLayer(
overlayRect: Rect.fromLTWH(offset.dx, offset.dy, size.width, size.height),
selection: selection,
- rootRenderObject: parent is RenderObject ? parent! as RenderObject : null,
+ rootRenderObject: parent is RenderObject ? parent! : null,
));
}
}
@@ -3213,14 +3264,14 @@
/// overlays in the same app (i.e. an storyboard), a selected or candidate
/// render object may not belong to this tree.
bool _isInInspectorRenderObjectTree(RenderObject child) {
- RenderObject? current = child.parent as RenderObject?;
+ RenderObject? current = child.parent;
while (current != null) {
// We found the widget inspector render object.
if (current is RenderStack
&& current.lastChild is _RenderInspectorOverlay) {
return rootRenderObject == current;
}
- current = current.parent as RenderObject?;
+ current = current.parent;
}
return false;
}
@@ -3578,7 +3629,6 @@
final Map<String, Object?> result = <String, Object?>{};
final Object? value = node.value;
if (_interactive) {
- result['objectId'] = service.toId(node, groupName!);
result['valueId'] = service.toId(value, groupName!);
}
if (summaryTree) {
@@ -3713,3 +3763,54 @@
// recognize the annotation.
// ignore: library_private_types_in_public_api
const _WidgetFactory widgetFactory = _WidgetFactory();
+
+/// Does not hold keys from garbage collection.
+@visibleForTesting
+class WeakMap<K, V> {
+ Expando<Object> _objects = Expando<Object>();
+
+ /// Strings, numbers, booleans.
+ final Map<K, V> _primitives = <K, V>{};
+
+ bool _isPrimitive(Object? key) {
+ return key == null || key is String || key is num || key is bool;
+ }
+
+ /// Returns the value for the given [key] or null if [key] is not in the map
+ /// or garbage collected.
+ ///
+ /// Does not support records to act as keys.
+ V? operator [](K key){
+ if (_isPrimitive(key)) {
+ return _primitives[key];
+ } else {
+ return _objects[key!] as V?;
+ }
+ }
+
+ /// Associates the [key] with the given [value].
+ void operator []=(K key, V value){
+ if (_isPrimitive(key)) {
+ _primitives[key] = value;
+ } else {
+ _objects[key!] = value;
+ }
+ }
+
+ /// Removes the value for the given [key] from the map.
+ V? remove(K key) {
+ if (_isPrimitive(key)) {
+ return _primitives.remove(key);
+ } else {
+ final V? result = _objects[key!] as V?;
+ _objects[key] = null;
+ return result;
+ }
+ }
+
+ /// Removes all pairs from the map.
+ void clear() {
+ _objects = Expando<Object>();
+ _primitives.clear();
+ }
+}
diff --git a/packages/flutter/lib/widgets.dart b/packages/flutter/lib/widgets.dart
index a24e287..fd2cf45 100644
--- a/packages/flutter/lib/widgets.dart
+++ b/packages/flutter/lib/widgets.dart
@@ -38,6 +38,7 @@
export 'src/widgets/context_menu_button_item.dart';
export 'src/widgets/context_menu_controller.dart';
export 'src/widgets/debug.dart';
+export 'src/widgets/decorated_sliver.dart';
export 'src/widgets/default_selection_style.dart';
export 'src/widgets/default_text_editing_shortcuts.dart';
export 'src/widgets/desktop_text_selection_toolbar_layout_delegate.dart';
diff --git a/packages/flutter/pubspec.yaml b/packages/flutter/pubspec.yaml
index c10bb90..391be87 100644
--- a/packages/flutter/pubspec.yaml
+++ b/packages/flutter/pubspec.yaml
@@ -12,7 +12,7 @@
material_color_utilities: 0.5.0
meta: 1.9.1
vector_math: 2.1.4
- web: 0.1.3-beta
+ web: 0.1.4-beta
sky_engine:
sdk: flutter
@@ -22,11 +22,11 @@
flutter_goldens:
sdk: flutter
fake_async: 1.3.1
- leak_tracker: 7.0.4
+ leak_tracker: 7.0.6
leak_tracker_testing: 1.0.0
- _fe_analyzer_shared: 61.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- analyzer: 5.13.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ _fe_analyzer_shared: 62.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ analyzer: 6.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
args: 2.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
async: 2.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -34,6 +34,7 @@
convert: 3.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
coverage: 1.6.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
crypto: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ dart_internal: 0.2.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
file: 6.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
frontend_server_client: 3.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
glob: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -41,6 +42,7 @@
http_parser: 4.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
intl: 0.18.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
io: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
logging: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
matcher: 0.12.16 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
mime: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -58,18 +60,18 @@
source_map_stack_trace: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_maps: 0.10.12 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test: 1.24.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_core: 0.5.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test: 1.24.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_core: 0.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- vm_service: 11.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ vm_service: 11.7.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
-# PUBSPEC CHECKSUM: d32a
+# PUBSPEC CHECKSUM: 46f2
diff --git a/packages/flutter/test/animation/animation_sheet_test.dart b/packages/flutter/test/animation/animation_sheet_test.dart
index 0c14e3f..4c26669 100644
--- a/packages/flutter/test/animation/animation_sheet_test.dart
+++ b/packages/flutter/test/animation/animation_sheet_test.dart
@@ -20,60 +20,6 @@
* because [matchesGoldenFile] does not use Skia Gold in its native package.
*/
- testWidgetsWithLeakTracking('correctly records frames using display', (WidgetTester tester) async {
- final AnimationSheetBuilder builder = AnimationSheetBuilder(frameSize: _DecuplePixels.size);
-
- await tester.pumpFrames(
- builder.record(
- const _DecuplePixels(Duration(seconds: 1)),
- ),
- const Duration(milliseconds: 200),
- const Duration(milliseconds: 100),
- );
-
- await tester.pumpFrames(
- builder.record(
- const _DecuplePixels(Duration(seconds: 1)),
- recording: false,
- ),
- const Duration(milliseconds: 200),
- const Duration(milliseconds: 100),
- );
-
- await tester.pumpFrames(
- builder.record(
- const _DecuplePixels(Duration(seconds: 1)),
- ),
- const Duration(milliseconds: 400),
- const Duration(milliseconds: 100),
- );
-
- // This test verifies deprecated methods.
- final Widget display = await builder.display(); // ignore: deprecated_member_use
- await tester.binding.setSurfaceSize(builder.sheetSize()); // ignore: deprecated_member_use
- await tester.pumpWidget(display);
-
- await expectLater(find.byWidget(display), matchesGoldenFile('test.animation_sheet_builder.records.png'));
- }, skip: isBrowser); // https://github.com/flutter/flutter/issues/56001
-
- testWidgetsWithLeakTracking('correctly wraps a row', (WidgetTester tester) async {
- final AnimationSheetBuilder builder = AnimationSheetBuilder(frameSize: _DecuplePixels.size);
-
- const Duration duration = Duration(seconds: 2);
- await tester.pumpFrames(
- builder.record(const _DecuplePixels(duration)),
- duration,
- const Duration(milliseconds: 200),
- );
-
- // This test verifies deprecated methods.
- final Widget display = await builder.display(); // ignore: deprecated_member_use
- await tester.binding.setSurfaceSize(builder.sheetSize(maxWidth: 80)); // ignore: deprecated_member_use
- await tester.pumpWidget(display);
-
- await expectLater(find.byWidget(display), matchesGoldenFile('test.animation_sheet_builder.wraps.png'));
- }, skip: isBrowser); // https://github.com/flutter/flutter/issues/56001
-
testWidgetsWithLeakTracking('correctly records frames using collate', (WidgetTester tester) async {
final AnimationSheetBuilder builder = AnimationSheetBuilder(frameSize: _DecuplePixels.size);
diff --git a/packages/flutter/test/cupertino/adaptive_text_selection_toolbar_test.dart b/packages/flutter/test/cupertino/adaptive_text_selection_toolbar_test.dart
index 0813e90..d0c6c1a 100644
--- a/packages/flutter/test/cupertino/adaptive_text_selection_toolbar_test.dart
+++ b/packages/flutter/test/cupertino/adaptive_text_selection_toolbar_test.dart
@@ -8,6 +8,7 @@
import 'package:flutter_test/flutter_test.dart';
import '../widgets/clipboard_utils.dart';
+import '../widgets/live_text_utils.dart';
void main() {
final MockClipboard mockClipboard = MockClipboard();
@@ -166,6 +167,7 @@
onCut: () {},
onPaste: () {},
onSelectAll: () {},
+ onLiveTextInput: () {},
),
),
));
@@ -178,13 +180,16 @@
switch (defaultTargetPlatform) {
case TargetPlatform.android:
+ expect(find.byType(CupertinoTextSelectionToolbarButton), findsNWidgets(5));
case TargetPlatform.fuchsia:
+ expect(find.byType(CupertinoTextSelectionToolbarButton), findsNWidgets(5));
case TargetPlatform.iOS:
- expect(find.byType(CupertinoTextSelectionToolbarButton), findsNWidgets(4));
+ expect(find.byType(CupertinoTextSelectionToolbarButton), findsNWidgets(5));
+ expect(findLiveTextButton(), findsOneWidget);
case TargetPlatform.macOS:
case TargetPlatform.linux:
case TargetPlatform.windows:
- expect(find.byType(CupertinoDesktopTextSelectionToolbarButton), findsNWidgets(4));
+ expect(find.byType(CupertinoDesktopTextSelectionToolbarButton), findsNWidgets(5));
}
},
skip: kIsWeb, // [intended] on web the browser handles the context menu.
diff --git a/packages/flutter/test/cupertino/dialog_test.dart b/packages/flutter/test/cupertino/dialog_test.dart
index 7f19ba2..64b15d3 100644
--- a/packages/flutter/test/cupertino/dialog_test.dart
+++ b/packages/flutter/test/cupertino/dialog_test.dart
@@ -1180,9 +1180,10 @@
expect(tester.getRect(find.byType(Placeholder)), placeholderRectWithoutInsets.translate(10, 10));
});
- testWidgets('Default cupertino dialog golden', (WidgetTester tester) async {
+ testWidgets('Material2 - Default cupertino dialog golden', (WidgetTester tester) async {
await tester.pumpWidget(
createAppWithButtonThatLaunchesDialog(
+ useMaterial3: false,
dialogBuilder: (BuildContext context) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(textScaleFactor: 3.0),
@@ -1206,7 +1207,38 @@
await expectLater(
find.byType(CupertinoAlertDialog),
- matchesGoldenFile('dialog_test.cupertino.default.png'),
+ matchesGoldenFile('m2_dialog_test.cupertino.default.png'),
+ );
+ });
+
+ testWidgets('Material3 - Default cupertino dialog golden', (WidgetTester tester) async {
+ await tester.pumpWidget(
+ createAppWithButtonThatLaunchesDialog(
+ useMaterial3: true,
+ dialogBuilder: (BuildContext context) {
+ return MediaQuery(
+ data: MediaQuery.of(context).copyWith(textScaleFactor: 3.0),
+ child: const RepaintBoundary(
+ child: CupertinoAlertDialog(
+ title: Text('Title'),
+ content: Text('text'),
+ actions: <Widget>[
+ CupertinoDialogAction(child: Text('No')),
+ CupertinoDialogAction(child: Text('OK')),
+ ],
+ ),
+ ),
+ );
+ },
+ ),
+ );
+
+ await tester.tap(find.text('Go'));
+ await tester.pumpAndSettle();
+
+ await expectLater(
+ find.byType(CupertinoAlertDialog),
+ matchesGoldenFile('m3_dialog_test.cupertino.default.png'),
);
});
@@ -1523,8 +1555,10 @@
Widget createAppWithButtonThatLaunchesDialog({
required WidgetBuilder dialogBuilder,
+ bool? useMaterial3,
}) {
return MaterialApp(
+ theme: ThemeData(useMaterial3: useMaterial3),
home: Material(
child: Center(
child: Builder(builder: (BuildContext context) {
diff --git a/packages/flutter/test/cupertino/switch_test.dart b/packages/flutter/test/cupertino/switch_test.dart
index f91fd0a..af9a133 100644
--- a/packages/flutter/test/cupertino/switch_test.dart
+++ b/packages/flutter/test/cupertino/switch_test.dart
@@ -753,6 +753,187 @@
);
});
+ PaintPattern onLabelPaintPattern({
+ required int alpha,
+ bool isRtl = false,
+ }) =>
+ paints
+ ..rect(
+ rect: Rect.fromLTWH(isRtl ? 43.5 : 14.5, 14.5, 1.0, 10.0),
+ color: const Color(0xffffffff).withAlpha(alpha),
+ style: PaintingStyle.fill,
+ );
+
+ PaintPattern offLabelPaintPattern({
+ required int alpha,
+ bool highContrast = false,
+ bool isRtl = false,
+ }) =>
+ paints
+ ..circle(
+ x: isRtl ? 16.0 : 43.0,
+ y: 19.5,
+ radius: 5.0,
+ color:
+ (highContrast ? const Color(0xffffffff) : const Color(0xffb3b3b3))
+ .withAlpha(alpha),
+ strokeWidth: 1.0,
+ style: PaintingStyle.stroke,
+ );
+
+ testWidgets('Switch renders switch labels correctly before, during, and after being tapped', (WidgetTester tester) async {
+ final Key switchKey = UniqueKey();
+ bool value = false;
+ await tester.pumpWidget(
+ MediaQuery(
+ data: const MediaQueryData(onOffSwitchLabels: true),
+ child: Directionality(
+ textDirection: TextDirection.ltr,
+ child: StatefulBuilder(
+ builder: (BuildContext context, StateSetter setState) {
+ return Center(
+ child: RepaintBoundary(
+ child: CupertinoSwitch(
+ key: switchKey,
+ value: value,
+ dragStartBehavior: DragStartBehavior.down,
+ onChanged: (bool newValue) {
+ setState(() {
+ value = newValue;
+ });
+ },
+ ),
+ ),
+ );
+ },
+ ),
+ ),
+ ),
+ );
+
+ final RenderObject switchRenderObject =
+ tester.element(find.byType(CupertinoSwitch)).renderObject!;
+
+ expect(switchRenderObject, offLabelPaintPattern(alpha: 255));
+ expect(switchRenderObject, onLabelPaintPattern(alpha: 0));
+
+ await tester.tap(find.byKey(switchKey));
+ expect(value, isTrue);
+
+ // Kick off animation, then advance to intermediate frame.
+ await tester.pump();
+ await tester.pump(const Duration(milliseconds: 60));
+ expect(switchRenderObject, onLabelPaintPattern(alpha: 131));
+ expect(switchRenderObject, offLabelPaintPattern(alpha: 124));
+
+ await tester.pumpAndSettle();
+ expect(switchRenderObject, onLabelPaintPattern(alpha: 255));
+ expect(switchRenderObject, offLabelPaintPattern(alpha: 0));
+ });
+
+ testWidgets('Switch renders switch labels correctly before, during, and after being tapped in high contrast', (WidgetTester tester) async {
+ final Key switchKey = UniqueKey();
+ bool value = false;
+ await tester.pumpWidget(
+ MediaQuery(
+ data: const MediaQueryData(
+ onOffSwitchLabels: true,
+ highContrast: true,
+ ),
+ child: Directionality(
+ textDirection: TextDirection.ltr,
+ child: StatefulBuilder(
+ builder: (BuildContext context, StateSetter setState) {
+ return Center(
+ child: RepaintBoundary(
+ child: CupertinoSwitch(
+ key: switchKey,
+ value: value,
+ dragStartBehavior: DragStartBehavior.down,
+ onChanged: (bool newValue) {
+ setState(() {
+ value = newValue;
+ });
+ },
+ ),
+ ),
+ );
+ },
+ ),
+ ),
+ ),
+ );
+
+ final RenderObject switchRenderObject =
+ tester.element(find.byType(CupertinoSwitch)).renderObject!;
+
+ expect(switchRenderObject, offLabelPaintPattern(highContrast: true, alpha: 255));
+ expect(switchRenderObject, onLabelPaintPattern(alpha: 0));
+
+ await tester.tap(find.byKey(switchKey));
+ expect(value, isTrue);
+
+ // Kick off animation, then advance to intermediate frame.
+ await tester.pump();
+ await tester.pump(const Duration(milliseconds: 60));
+ expect(switchRenderObject, onLabelPaintPattern(alpha: 131));
+ expect(switchRenderObject, offLabelPaintPattern(highContrast: true, alpha: 124));
+
+ await tester.pumpAndSettle();
+ expect(switchRenderObject, onLabelPaintPattern(alpha: 255));
+ expect(switchRenderObject, offLabelPaintPattern(highContrast: true, alpha: 0));
+ });
+
+ testWidgets('Switch renders switch labels correctly before, during, and after being tapped with direction rtl', (WidgetTester tester) async {
+ final Key switchKey = UniqueKey();
+ bool value = false;
+ await tester.pumpWidget(
+ MediaQuery(
+ data: const MediaQueryData(onOffSwitchLabels: true),
+ child: Directionality(
+ textDirection: TextDirection.rtl,
+ child: StatefulBuilder(
+ builder: (BuildContext context, StateSetter setState) {
+ return Center(
+ child: RepaintBoundary(
+ child: CupertinoSwitch(
+ key: switchKey,
+ value: value,
+ dragStartBehavior: DragStartBehavior.down,
+ onChanged: (bool newValue) {
+ setState(() {
+ value = newValue;
+ });
+ },
+ ),
+ ),
+ );
+ },
+ ),
+ ),
+ ),
+ );
+
+ final RenderObject switchRenderObject =
+ tester.element(find.byType(CupertinoSwitch)).renderObject!;
+
+ expect(switchRenderObject, offLabelPaintPattern(isRtl: true, alpha: 255));
+ expect(switchRenderObject, onLabelPaintPattern(isRtl: true, alpha: 0));
+
+ await tester.tap(find.byKey(switchKey));
+ expect(value, isTrue);
+
+ // Kick off animation, then advance to intermediate frame.
+ await tester.pump();
+ await tester.pump(const Duration(milliseconds: 60));
+ expect(switchRenderObject, onLabelPaintPattern(isRtl: true, alpha: 131));
+ expect(switchRenderObject, offLabelPaintPattern(isRtl: true, alpha: 124));
+
+ await tester.pumpAndSettle();
+ expect(switchRenderObject, onLabelPaintPattern(isRtl: true, alpha: 255));
+ expect(switchRenderObject, offLabelPaintPattern(isRtl: true, alpha: 0));
+ });
+
testWidgets('Switch renders correctly in dark mode', (WidgetTester tester) async {
final Key switchKey = UniqueKey();
bool value = false;
diff --git a/packages/flutter/test/cupertino/text_field_test.dart b/packages/flutter/test/cupertino/text_field_test.dart
index 5e869ca..ab0b3fb 100644
--- a/packages/flutter/test/cupertino/text_field_test.dart
+++ b/packages/flutter/test/cupertino/text_field_test.dart
@@ -21,6 +21,7 @@
import '../rendering/mock_canvas.dart';
import '../widgets/clipboard_utils.dart';
import '../widgets/editable_text_utils.dart' show OverflowWidgetTextEditingController;
+import '../widgets/live_text_utils.dart';
import '../widgets/semantics_tester.dart';
// On web, the context menu (aka toolbar) is provided by the browser.
@@ -199,12 +200,56 @@
Offset textOffsetToPosition(WidgetTester tester, int offset) => textOffsetToBottomLeftPosition(tester, offset) + const Offset(kIsWeb ? 1 : 0, -2);
setUp(() async {
+ TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, mockClipboard.handleMethodCall);
EditableText.debugDeterministicCursor = false;
// Fill the clipboard so that the Paste option is available in the text
// selection menu.
await Clipboard.setData(const ClipboardData(text: 'Clipboard data'));
});
+
+ testWidgets(
+ 'Live Text button shows and hides correctly when LiveTextStatus changes',
+ (WidgetTester tester) async {
+ final LiveTextInputTester liveTextInputTester = LiveTextInputTester();
+ addTearDown(liveTextInputTester.dispose);
+
+ final TextEditingController controller = TextEditingController(text: '');
+ const Key key = ValueKey<String>('TextField');
+ final FocusNode focusNode = FocusNode();
+ final Widget app = MaterialApp(
+ theme: ThemeData(platform: TargetPlatform.iOS),
+ home: Scaffold(
+ body: Center(
+ child: CupertinoTextField(
+ key: key,
+ controller: controller,
+ focusNode: focusNode,
+ ),
+ ),
+ ),
+ );
+
+ liveTextInputTester.mockLiveTextInputEnabled = true;
+ await tester.pumpWidget(app);
+ focusNode.requestFocus();
+ await tester.pumpAndSettle();
+
+ final Finder textFinder = find.byType(EditableText);
+ await tester.longPress(textFinder);
+ await tester.pumpAndSettle();
+ expect(
+ findLiveTextButton(),
+ kIsWeb ? findsNothing : findsOneWidget,
+ );
+
+ liveTextInputTester.mockLiveTextInputEnabled = false;
+ await tester.longPress(textFinder);
+ await tester.pumpAndSettle();
+ expect(findLiveTextButton(), findsNothing);
+ },
+ );
+
testWidgets('can use the desktop cut/copy/paste buttons on Mac', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'blah1 blah2',
@@ -1545,7 +1590,7 @@
Text text = tester.widget<Text>(find.text('Paste'));
expect(text.style!.color!.value, CupertinoColors.black.value);
- expect(text.style!.fontSize, 14);
+ expect(text.style!.fontSize, 15);
expect(text.style!.letterSpacing, -0.15);
expect(text.style!.fontWeight, FontWeight.w400);
@@ -1577,7 +1622,7 @@
text = tester.widget<Text>(find.text('Paste'));
// The toolbar buttons' text are still the same style.
expect(text.style!.color!.value, CupertinoColors.white.value);
- expect(text.style!.fontSize, 14);
+ expect(text.style!.fontSize, 15);
expect(text.style!.letterSpacing, -0.15);
expect(text.style!.fontWeight, FontWeight.w400);
}, skip: isContextMenuProvidedByPlatform); // [intended] only applies to platforms where we supply the context menu.
@@ -6537,7 +6582,7 @@
topMatcher: moreOrLessEquals(bottomLeftSelectionPosition.dy + 8, epsilon: 0.01),
leftMatcher: moreOrLessEquals(8),
rightMatcher: lessThanOrEqualTo(400 - 8),
- bottomMatcher: moreOrLessEquals(bottomLeftSelectionPosition.dy + 8 + 43, epsilon: 0.01),
+ bottomMatcher: moreOrLessEquals(bottomLeftSelectionPosition.dy + 8 + 45, epsilon: 0.01),
),
),
);
@@ -6597,7 +6642,7 @@
pathMatcher: PathBoundsMatcher(
topMatcher: moreOrLessEquals(bottomLeftSelectionPosition.dy + 8, epsilon: 0.01),
rightMatcher: moreOrLessEquals(400.0 - 8),
- bottomMatcher: moreOrLessEquals(bottomLeftSelectionPosition.dy + 8 + 43, epsilon: 0.01),
+ bottomMatcher: moreOrLessEquals(bottomLeftSelectionPosition.dy + 8 + 45, epsilon: 0.01),
leftMatcher: greaterThanOrEqualTo(8),
),
),
@@ -6650,7 +6695,7 @@
paints..clipPath(
pathMatcher: PathBoundsMatcher(
bottomMatcher: moreOrLessEquals(bottomLeftSelectionPosition.dy - 8 - lineHeight, epsilon: 0.01),
- topMatcher: moreOrLessEquals(bottomLeftSelectionPosition.dy - 8 - lineHeight - 43, epsilon: 0.01),
+ topMatcher: moreOrLessEquals(bottomLeftSelectionPosition.dy - 8 - lineHeight - 45, epsilon: 0.01),
rightMatcher: lessThanOrEqualTo(400 - 8),
leftMatcher: greaterThanOrEqualTo(8),
),
@@ -6719,7 +6764,7 @@
paints..clipPath(
pathMatcher: PathBoundsMatcher(
bottomMatcher: moreOrLessEquals(selectionPosition.dy - 8 - lineHeight, epsilon: 0.01),
- topMatcher: moreOrLessEquals(selectionPosition.dy - 8 - lineHeight - 43, epsilon: 0.01),
+ topMatcher: moreOrLessEquals(selectionPosition.dy - 8 - lineHeight - 45, epsilon: 0.01),
rightMatcher: lessThanOrEqualTo(400 - 8),
leftMatcher: greaterThanOrEqualTo(8),
),
@@ -6792,7 +6837,7 @@
paints..clipPath(
pathMatcher: PathBoundsMatcher(
bottomMatcher: moreOrLessEquals(selectionPosition.dy - 8 - lineHeight, epsilon: 0.01),
- topMatcher: moreOrLessEquals(selectionPosition.dy - 8 - lineHeight - 43, epsilon: 0.01),
+ topMatcher: moreOrLessEquals(selectionPosition.dy - 8 - lineHeight - 45, epsilon: 0.01),
rightMatcher: lessThanOrEqualTo(400 - 8),
leftMatcher: greaterThanOrEqualTo(8),
),
diff --git a/packages/flutter/test/cupertino/text_selection_test.dart b/packages/flutter/test/cupertino/text_selection_test.dart
index ed65377..b679eb6 100644
--- a/packages/flutter/test/cupertino/text_selection_test.dart
+++ b/packages/flutter/test/cupertino/text_selection_test.dart
@@ -60,18 +60,6 @@
TestWidgetsFlutterBinding.ensureInitialized();
final MockClipboard mockClipboard = MockClipboard();
- // Returns true iff the button is visually enabled.
- bool appearsEnabled(WidgetTester tester, String text) {
- final CupertinoButton button = tester.widget<CupertinoButton>(
- find.ancestor(
- of: find.text(text),
- matching: find.byType(CupertinoButton),
- ),
- );
- // Disabled buttons have no opacity change when pressed.
- return button.pressedOpacity! < 1.0;
- }
-
List<TextSelectionPoint> globalize(Iterable<TextSelectionPoint> points, RenderBox box) {
return points.map<TextSelectionPoint>((TextSelectionPoint point) {
return TextSelectionPoint(
@@ -191,6 +179,15 @@
});
group('Text selection menu overflow (iOS)', () {
+ Finder findOverflowNextButton() => find.byWidgetPredicate((Widget widget) =>
+ widget is CustomPaint &&
+ '${widget.painter?.runtimeType}' == '_RightCupertinoChevronPainter',
+ );
+ Finder findOverflowBackButton() => find.byWidgetPredicate((Widget widget) =>
+ widget is CustomPaint &&
+ '${widget.painter?.runtimeType}' == '_LeftCupertinoChevronPainter',
+ );
+
testWidgets('All menu items show when they fit.', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController(text: 'abc def ghi');
await tester.pumpWidget(CupertinoApp(
@@ -216,8 +213,8 @@
expect(find.text('Copy'), findsNothing);
expect(find.text('Paste'), findsNothing);
expect(find.text('Select All'), findsNothing);
- expect(find.text('◀'), findsNothing);
- expect(find.text('▶'), findsNothing);
+ expect(findOverflowBackButton(), findsNothing);
+ expect(findOverflowNextButton(), findsNothing);
// Long press on an empty space to show the selection menu.
await tester.longPressAt(textOffsetToPosition(tester, 4));
@@ -226,8 +223,8 @@
expect(find.text('Copy'), findsNothing);
expect(find.text('Paste'), findsOneWidget);
expect(find.text('Select All'), findsOneWidget);
- expect(find.text('◀'), findsNothing);
- expect(find.text('▶'), findsNothing);
+ expect(findOverflowBackButton(), findsNothing);
+ expect(findOverflowNextButton(), findsNothing);
// Double tap to select a word and show the full selection menu.
final Offset textOffset = textOffsetToPosition(tester, 1);
@@ -241,8 +238,8 @@
expect(find.text('Copy'), findsOneWidget);
expect(find.text('Paste'), findsOneWidget);
expect(find.text('Select All'), findsNothing);
- expect(find.text('◀'), findsNothing);
- expect(find.text('▶'), findsNothing);
+ expect(findOverflowBackButton(), findsNothing);
+ expect(findOverflowNextButton(), findsNothing);
},
skip: isBrowser, // [intended] We do not use Flutter-rendered context menu on the Web.
variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS }),
@@ -273,8 +270,8 @@
expect(find.text('Copy'), findsNothing);
expect(find.text('Paste'), findsNothing);
expect(find.text('Select All'), findsNothing);
- expect(find.text('◀'), findsNothing);
- expect(find.text('▶'), findsNothing);
+ expect(findOverflowBackButton(), findsNothing);
+ expect(findOverflowNextButton(), findsNothing);
// Double tap to select a word and show the selection menu.
final Offset textOffset = textOffsetToPosition(tester, 1);
@@ -288,32 +285,29 @@
expect(find.text('Copy'), findsOneWidget);
expect(find.text('Paste'), findsNothing);
expect(find.text('Select All'), findsNothing);
- expect(find.text('◀'), findsNothing);
- expect(find.text('▶'), findsOneWidget);
- expect(appearsEnabled(tester, '▶'), true);
+ expect(findOverflowBackButton(), findsNothing);
+ expect(findOverflowNextButton(), findsOneWidget);
- // Tapping the next button shows the overflowing button.
- await tester.tap(find.text('▶'));
+ // Tapping the next button shows the overflowing button and the next
+ // button is hidden as the last page is shown.
+ await tester.tapAt(tester.getCenter(findOverflowNextButton()));
await tester.pumpAndSettle();
expect(find.text('Cut'), findsNothing);
expect(find.text('Copy'), findsNothing);
expect(find.text('Paste'), findsOneWidget);
expect(find.text('Select All'), findsNothing);
- expect(find.text('◀'), findsOneWidget);
- expect(appearsEnabled(tester, '◀'), true);
- expect(find.text('▶'), findsOneWidget);
- expect(appearsEnabled(tester, '▶'), false);
+ expect(findOverflowBackButton(), findsOneWidget);
+ expect(findOverflowNextButton(), findsNothing);
- // Tapping the back button shows the first page again.
- await tester.tap(find.text('◀'));
+ // Tapping the back button shows the first page again with the next button.
+ await tester.tapAt(tester.getCenter(findOverflowBackButton()));
await tester.pumpAndSettle();
expect(find.text('Cut'), findsOneWidget);
expect(find.text('Copy'), findsOneWidget);
expect(find.text('Paste'), findsNothing);
expect(find.text('Select All'), findsNothing);
- expect(find.text('◀'), findsNothing);
- expect(find.text('▶'), findsOneWidget);
- expect(appearsEnabled(tester, '▶'), true);
+ expect(findOverflowBackButton(), findsNothing);
+ expect(findOverflowNextButton(), findsOneWidget);
},
skip: isBrowser, // [intended] We do not use Flutter-rendered context menu on the Web.
variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS }),
@@ -341,13 +335,13 @@
));
// Initially, the menu isn't shown at all.
- expect(find.byType(CupertinoButton), findsNothing);
+ expect(find.byType(CupertinoTextSelectionToolbarButton), findsNothing);
expect(find.text('Cut'), findsNothing);
expect(find.text('Copy'), findsNothing);
expect(find.text('Paste'), findsNothing);
expect(find.text('Select All'), findsNothing);
- expect(find.text('◀'), findsNothing);
- expect(find.text('▶'), findsNothing);
+ expect(findOverflowBackButton(), findsNothing);
+ expect(findOverflowNextButton(), findsNothing);
// Double tap to select a word and show the selection menu.
final Offset textOffset = textOffsetToPosition(tester, 1);
@@ -357,65 +351,58 @@
await tester.pumpAndSettle();
// Only the first button fits, and a next button is shown.
- expect(find.byType(CupertinoButton), findsNWidgets(2));
+ expect(find.byType(CupertinoTextSelectionToolbarButton), findsNWidgets(2));
expect(find.text('Cut'), findsOneWidget);
expect(find.text('Copy'), findsNothing);
expect(find.text('Paste'), findsNothing);
expect(find.text('Select All'), findsNothing);
- expect(find.text('◀'), findsNothing);
- expect(find.text('▶'), findsOneWidget);
- expect(appearsEnabled(tester, '▶'), true);
+ expect(findOverflowBackButton(), findsNothing);
+ expect(findOverflowNextButton(), findsOneWidget);
// Tapping the next button shows Copy.
- await tester.tap(find.text('▶'));
+ await tester.tapAt(tester.getCenter(findOverflowNextButton()));
await tester.pumpAndSettle();
- expect(find.byType(CupertinoButton), findsNWidgets(3));
+ expect(find.byType(CupertinoTextSelectionToolbarButton), findsNWidgets(3));
expect(find.text('Cut'), findsNothing);
expect(find.text('Copy'), findsOneWidget);
expect(find.text('Paste'), findsNothing);
expect(find.text('Select All'), findsNothing);
- expect(find.text('◀'), findsOneWidget);
- expect(appearsEnabled(tester, '◀'), true);
- expect(find.text('▶'), findsOneWidget);
- expect(appearsEnabled(tester, '▶'), true);
+ expect(findOverflowBackButton(), findsOneWidget);
+ expect(findOverflowNextButton(), findsOneWidget);
- // Tapping the next button again shows Paste.
- await tester.tap(find.text('▶'));
+ // Tapping the next button again shows Paste and hides the next button as
+ // the last page is shown.
+ await tester.tapAt(tester.getCenter(findOverflowNextButton()));
await tester.pumpAndSettle();
- expect(find.byType(CupertinoButton), findsNWidgets(3));
+ expect(find.byType(CupertinoTextSelectionToolbarButton), findsNWidgets(2));
expect(find.text('Cut'), findsNothing);
expect(find.text('Copy'), findsNothing);
expect(find.text('Paste'), findsOneWidget);
expect(find.text('Select All'), findsNothing);
- expect(find.text('◀'), findsOneWidget);
- expect(appearsEnabled(tester, '◀'), true);
- expect(find.text('▶'), findsOneWidget);
- expect(appearsEnabled(tester, '▶'), false);
+ expect(findOverflowBackButton(), findsOneWidget);
+ expect(findOverflowNextButton(), findsNothing);
- // Tapping the back button shows the second page again.
- await tester.tap(find.text('◀'));
+ // Tapping the back button shows the second page again with the next button.
+ await tester.tapAt(tester.getCenter(findOverflowBackButton()));
await tester.pumpAndSettle();
- expect(find.byType(CupertinoButton), findsNWidgets(3));
+ expect(find.byType(CupertinoTextSelectionToolbarButton), findsNWidgets(3));
expect(find.text('Cut'), findsNothing);
expect(find.text('Copy'), findsOneWidget);
expect(find.text('Paste'), findsNothing);
expect(find.text('Select All'), findsNothing);
- expect(find.text('◀'), findsOneWidget);
- expect(appearsEnabled(tester, '◀'), true);
- expect(find.text('▶'), findsOneWidget);
- expect(appearsEnabled(tester, '▶'), true);
+ expect(findOverflowBackButton(), findsOneWidget);
+ expect(findOverflowNextButton(), findsOneWidget);
// Tapping the back button again shows the first page again.
- await tester.tap(find.text('◀'));
+ await tester.tapAt(tester.getCenter(findOverflowBackButton()));
await tester.pumpAndSettle();
- expect(find.byType(CupertinoButton), findsNWidgets(2));
+ expect(find.byType(CupertinoTextSelectionToolbarButton), findsNWidgets(2));
expect(find.text('Cut'), findsOneWidget);
expect(find.text('Copy'), findsNothing);
expect(find.text('Paste'), findsNothing);
expect(find.text('Select All'), findsNothing);
- expect(find.text('◀'), findsNothing);
- expect(find.text('▶'), findsOneWidget);
- expect(appearsEnabled(tester, '▶'), true);
+ expect(findOverflowBackButton(), findsNothing);
+ expect(findOverflowNextButton(), findsOneWidget);
},
skip: isBrowser, // [intended] We do not use Flutter-rendered context menu on the Web.
variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS }),
@@ -452,8 +439,8 @@
expect(find.text(_longLocalizations.copyButtonLabel), findsNothing);
expect(find.text(_longLocalizations.pasteButtonLabel), findsNothing);
expect(find.text(_longLocalizations.selectAllButtonLabel), findsNothing);
- expect(find.text('◀'), findsNothing);
- expect(find.text('▶'), findsNothing);
+ expect(findOverflowBackButton(), findsNothing);
+ expect(findOverflowNextButton(), findsNothing);
// Long press on an empty space to show the selection menu, with only the
// paste button visible.
@@ -463,21 +450,18 @@
expect(find.text(_longLocalizations.copyButtonLabel), findsNothing);
expect(find.text(_longLocalizations.pasteButtonLabel), findsOneWidget);
expect(find.text(_longLocalizations.selectAllButtonLabel), findsNothing);
- expect(find.text('◀'), findsNothing);
- expect(find.text('▶'), findsOneWidget);
- expect(appearsEnabled(tester, '▶'), true);
+ expect(findOverflowBackButton(), findsNothing);
+ expect(findOverflowNextButton(), findsOneWidget);
// Tap next to go to the second and final page.
- await tester.tap(find.text('▶'));
+ await tester.tapAt(tester.getCenter(findOverflowNextButton()));
await tester.pumpAndSettle();
expect(find.text(_longLocalizations.cutButtonLabel), findsNothing);
expect(find.text(_longLocalizations.copyButtonLabel), findsNothing);
expect(find.text(_longLocalizations.pasteButtonLabel), findsNothing);
expect(find.text(_longLocalizations.selectAllButtonLabel), findsOneWidget);
- expect(find.text('◀'), findsOneWidget);
- expect(find.text('▶'), findsOneWidget);
- expect(appearsEnabled(tester, '◀'), true);
- expect(appearsEnabled(tester, '▶'), false);
+ expect(findOverflowBackButton(), findsOneWidget);
+ expect(findOverflowNextButton(), findsNothing);
// Tap select all to show the full selection menu.
await tester.tap(find.text(_longLocalizations.selectAllButtonLabel));
@@ -488,56 +472,48 @@
expect(find.text(_longLocalizations.copyButtonLabel), findsNothing);
expect(find.text(_longLocalizations.pasteButtonLabel), findsNothing);
expect(find.text(_longLocalizations.selectAllButtonLabel), findsNothing);
- expect(find.text('◀'), findsNothing);
- expect(find.text('▶'), findsOneWidget);
- expect(appearsEnabled(tester, '▶'), true);
+ expect(findOverflowBackButton(), findsNothing);
+ expect(findOverflowNextButton(), findsOneWidget);
// Tap next to go to the second page.
- await tester.tap(find.text('▶'));
+ await tester.tapAt(tester.getCenter(findOverflowNextButton()));
await tester.pumpAndSettle();
expect(find.text(_longLocalizations.cutButtonLabel), findsNothing);
expect(find.text(_longLocalizations.copyButtonLabel), findsOneWidget);
expect(find.text(_longLocalizations.pasteButtonLabel), findsNothing);
expect(find.text(_longLocalizations.selectAllButtonLabel), findsNothing);
- expect(find.text('◀'), findsOneWidget);
- expect(find.text('▶'), findsOneWidget);
- expect(appearsEnabled(tester, '◀'), true);
- expect(appearsEnabled(tester, '▶'), true);
+ expect(findOverflowBackButton(), findsOneWidget);
+ expect(findOverflowNextButton(), findsOneWidget);
// Tap next to go to the third and final page.
- await tester.tap(find.text('▶'));
+ await tester.tapAt(tester.getCenter(findOverflowNextButton()));
await tester.pumpAndSettle();
expect(find.text(_longLocalizations.cutButtonLabel), findsNothing);
expect(find.text(_longLocalizations.copyButtonLabel), findsNothing);
expect(find.text(_longLocalizations.pasteButtonLabel), findsOneWidget);
expect(find.text(_longLocalizations.selectAllButtonLabel), findsNothing);
- expect(find.text('◀'), findsOneWidget);
- expect(find.text('▶'), findsOneWidget);
- expect(appearsEnabled(tester, '◀'), true);
- expect(appearsEnabled(tester, '▶'), false);
+ expect(findOverflowBackButton(), findsOneWidget);
+ expect(findOverflowNextButton(), findsNothing);
// Tap back to go to the second page again.
- await tester.tap(find.text('◀'));
+ await tester.tapAt(tester.getCenter(findOverflowBackButton()));
await tester.pumpAndSettle();
expect(find.text(_longLocalizations.cutButtonLabel), findsNothing);
expect(find.text(_longLocalizations.copyButtonLabel), findsOneWidget);
expect(find.text(_longLocalizations.pasteButtonLabel), findsNothing);
expect(find.text(_longLocalizations.selectAllButtonLabel), findsNothing);
- expect(find.text('◀'), findsOneWidget);
- expect(find.text('▶'), findsOneWidget);
- expect(appearsEnabled(tester, '◀'), true);
- expect(appearsEnabled(tester, '▶'), true);
+ expect(findOverflowBackButton(), findsOneWidget);
+ expect(findOverflowNextButton(), findsOneWidget);
// Tap back to go to the first page again.
- await tester.tap(find.text('◀'));
+ await tester.tapAt(tester.getCenter(findOverflowBackButton()));
await tester.pumpAndSettle();
expect(find.text(_longLocalizations.cutButtonLabel), findsOneWidget);
expect(find.text(_longLocalizations.copyButtonLabel), findsNothing);
expect(find.text(_longLocalizations.pasteButtonLabel), findsNothing);
expect(find.text(_longLocalizations.selectAllButtonLabel), findsNothing);
- expect(find.text('◀'), findsNothing);
- expect(find.text('▶'), findsOneWidget);
- expect(appearsEnabled(tester, '▶'), true);
+ expect(findOverflowBackButton(), findsNothing);
+ expect(findOverflowNextButton(), findsOneWidget);
},
skip: isBrowser, // [intended] We do not use Flutter-rendered context menu on the Web.
variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS }),
@@ -572,8 +548,8 @@
expect(find.text('Copy'), findsNothing);
expect(find.text('Paste'), findsNothing);
expect(find.text('Select All'), findsNothing);
- expect(find.text('◀'), findsNothing);
- expect(find.text('▶'), findsNothing);
+ expect(findOverflowBackButton(), findsNothing);
+ expect(findOverflowNextButton(), findsNothing);
// Long press on an space to show the selection menu.
await tester.longPressAt(textOffsetToPosition(tester, 1));
@@ -582,8 +558,8 @@
expect(find.text('Copy'), findsNothing);
expect(find.text('Paste'), findsOneWidget);
expect(find.text('Select All'), findsOneWidget);
- expect(find.text('◀'), findsNothing);
- expect(find.text('▶'), findsNothing);
+ expect(findOverflowBackButton(), findsNothing);
+ expect(findOverflowNextButton(), findsNothing);
// Tap to select all.
await tester.tap(find.text('Select All'));
@@ -594,8 +570,8 @@
expect(find.text('Copy'), findsOneWidget);
expect(find.text('Paste'), findsOneWidget);
expect(find.text('Select All'), findsNothing);
- expect(find.text('◀'), findsNothing);
- expect(find.text('▶'), findsNothing);
+ expect(findOverflowBackButton(), findsNothing);
+ expect(findOverflowNextButton(), findsNothing);
// The menu appears at the top of the visible selection.
final Offset selectionOffset = tester
@@ -603,8 +579,8 @@
final Offset textFieldOffset =
tester.getTopLeft(find.byType(CupertinoTextField));
- // 7.0 + 43.0 + 8.0 - 8.0 = _kToolbarArrowSize + _kToolbarHeight + _kToolbarContentDistance - padding
- expect(selectionOffset.dy + 7.0 + 43.0 + 8.0 - 8.0, equals(textFieldOffset.dy));
+ // 7.0 + 45.0 + 8.0 - 8.0 = _kToolbarArrowSize + _kToolbarHeight + _kToolbarContentDistance - padding
+ expect(selectionOffset.dy + 7.0 + 45.0 + 8.0 - 8.0, equals(textFieldOffset.dy));
},
skip: isBrowser, // [intended] the selection menu isn't required by web
variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS }),
diff --git a/packages/flutter/test/cupertino/text_selection_toolbar_button_test.dart b/packages/flutter/test/cupertino/text_selection_toolbar_button_test.dart
index 708183b..76eee86 100644
--- a/packages/flutter/test/cupertino/text_selection_toolbar_button_test.dart
+++ b/packages/flutter/test/cupertino/text_selection_toolbar_button_test.dart
@@ -29,7 +29,7 @@
expect(pressed, true);
});
- testWidgets('pressedOpacity defaults to 0.1', (WidgetTester tester) async {
+ testWidgets('background darkens when pressed', (WidgetTester tester) async {
await tester.pumpWidget(
CupertinoApp(
home: Center(
@@ -41,35 +41,38 @@
),
);
- // Original at full opacity.
- FadeTransition opacity = tester.widget(find.descendant(
- of: find.byType(CupertinoTextSelectionToolbarButton),
- matching: find.byType(FadeTransition),
+ // Original with transparent background.
+ DecoratedBox decoratedBox = tester.widget(find.descendant(
+ of: find.byType(CupertinoButton),
+ matching: find.byType(DecoratedBox),
));
- expect(opacity.opacity.value, 1.0);
+ BoxDecoration boxDecoration = decoratedBox.decoration as BoxDecoration;
+ expect(boxDecoration.color, const Color(0x00000000));
// Make a "down" gesture on the button.
final Offset center = tester.getCenter(find.byType(CupertinoTextSelectionToolbarButton));
final TestGesture gesture = await tester.startGesture(center);
await tester.pumpAndSettle();
- // Opacity reduces during the down gesture.
- opacity = tester.widget(find.descendant(
+ // When pressed, the background darkens.
+ decoratedBox = tester.widget(find.descendant(
of: find.byType(CupertinoTextSelectionToolbarButton),
- matching: find.byType(FadeTransition),
+ matching: find.byType(DecoratedBox),
));
- expect(opacity.opacity.value, 0.7);
+ boxDecoration = decoratedBox.decoration as BoxDecoration;
+ expect(boxDecoration.color!.value, const Color(0x10000000).value);
// Release the down gesture.
await gesture.up();
await tester.pumpAndSettle();
- // Opacity is back to normal.
- opacity = tester.widget(find.descendant(
+ // Color is back to transparent.
+ decoratedBox = tester.widget(find.descendant(
of: find.byType(CupertinoTextSelectionToolbarButton),
- matching: find.byType(FadeTransition),
+ matching: find.byType(DecoratedBox),
));
- expect(opacity.opacity.value, 1.0);
+ boxDecoration = decoratedBox.decoration as BoxDecoration;
+ expect(boxDecoration.color, const Color(0x00000000));
});
testWidgets('passing null to onPressed disables the button', (WidgetTester tester) async {
diff --git a/packages/flutter/test/cupertino/text_selection_toolbar_test.dart b/packages/flutter/test/cupertino/text_selection_toolbar_test.dart
index 98a5601..5c110b2 100644
--- a/packages/flutter/test/cupertino/text_selection_toolbar_test.dart
+++ b/packages/flutter/test/cupertino/text_selection_toolbar_test.dart
@@ -6,12 +6,13 @@
import 'package:flutter/foundation.dart';
import 'package:flutter_test/flutter_test.dart';
+import '../rendering/mock_canvas.dart';
import '../widgets/editable_text_utils.dart' show textOffsetToPosition;
// These constants are copied from cupertino/text_selection_toolbar.dart.
const double _kArrowScreenPadding = 26.0;
const double _kToolbarContentDistance = 8.0;
-const double _kToolbarHeight = 43.0;
+const double _kToolbarHeight = 45.0;
// A custom text selection menu that just displays a single custom button.
class _CustomCupertinoTextSelectionControls extends CupertinoTextSelectionControls {
@@ -60,9 +61,9 @@
static const double itemWidth = 100.0;
}
-const CupertinoDynamicColor _kToolbarBackgroundColor = CupertinoDynamicColor.withBrightness(
- color: Color(0xEBF7F7F7),
- darkColor: Color(0xEB202020),
+const CupertinoDynamicColor _kToolbarTextColor = CupertinoDynamicColor.withBrightness(
+ color: CupertinoColors.black,
+ darkColor: CupertinoColors.white,
);
void main() {
@@ -81,8 +82,65 @@
// visible part of the toolbar for use in measurements.
Finder findToolbar() => findPrivate('_CupertinoTextSelectionToolbarContent');
- Finder findOverflowNextButton() => find.text('▶');
- Finder findOverflowBackButton() => find.text('◀');
+ // Check if the middle point of the chevron is pointing left or right.
+ //
+ // Offset.dx: a right or left margin (_kToolbarChevronSize / 4 => 2.5) to center the icon horizontally
+ // Offset.dy: always in the exact vertical center (_kToolbarChevronSize / 2 => 5)
+ PaintPattern overflowNextPaintPattern() => paints
+ ..line(p1: const Offset(2.5, 0), p2: const Offset(7.5, 5))
+ ..line(p1: const Offset(7.5, 5), p2: const Offset(2.5, 10));
+ PaintPattern overflowBackPaintPattern() => paints
+ ..line(p1: const Offset(7.5, 0), p2: const Offset(2.5, 5))
+ ..line(p1: const Offset(2.5, 5), p2: const Offset(7.5, 10));
+
+ Finder findOverflowNextButton() => find.byWidgetPredicate((Widget widget) =>
+ widget is CustomPaint &&
+ '${widget.painter?.runtimeType}' == '_RightCupertinoChevronPainter',
+ );
+ Finder findOverflowBackButton() => find.byWidgetPredicate((Widget widget) =>
+ widget is CustomPaint &&
+ '${widget.painter?.runtimeType}' == '_LeftCupertinoChevronPainter',
+ );
+
+ testWidgets('chevrons point to the correct side', (WidgetTester tester) async {
+ // Add enough TestBoxes to need 3 pages.
+ final List<Widget> children = List<Widget>.generate(15, (int i) => const TestBox());
+ await tester.pumpWidget(
+ CupertinoApp(
+ home: Center(
+ child: CupertinoTextSelectionToolbar(
+ anchorAbove: const Offset(50.0, 100.0),
+ anchorBelow: const Offset(50.0, 200.0),
+ children: children,
+ ),
+ ),
+ ),
+ );
+
+ expect(findOverflowBackButton(), findsNothing);
+ expect(findOverflowNextButton(), findsOneWidget);
+
+ expect(findOverflowNextButton(), overflowNextPaintPattern());
+
+ // Tap the overflow next button to show the next page of children.
+ await tester.tapAt(tester.getCenter(findOverflowNextButton()));
+ await tester.pumpAndSettle();
+
+ expect(findOverflowBackButton(), findsOneWidget);
+ expect(findOverflowNextButton(), findsOneWidget);
+
+ expect(findOverflowBackButton(), overflowBackPaintPattern());
+ expect(findOverflowNextButton(), overflowNextPaintPattern());
+
+ // Tap the overflow next button to show the last page of children.
+ await tester.tapAt(tester.getCenter(findOverflowNextButton()));
+ await tester.pumpAndSettle();
+
+ expect(findOverflowBackButton(), findsOneWidget);
+ expect(findOverflowNextButton(), findsNothing);
+
+ expect(findOverflowBackButton(), overflowBackPaintPattern());
+ }, skip: kIsWeb); // Path.combine is not implemented in the HTML backend https://github.com/flutter/flutter/issues/44572
testWidgets('paginates children if they overflow', (WidgetTester tester) async {
late StateSetter setState;
@@ -121,22 +179,15 @@
expect(findOverflowBackButton(), findsNothing);
// Tap the overflow next button to show the next page of children.
- await tester.tap(findOverflowNextButton());
+ // The next button is hidden as there's no next page.
+ await tester.tapAt(tester.getCenter(findOverflowNextButton()));
await tester.pumpAndSettle();
expect(find.byType(TestBox), findsNWidgets(1));
- expect(findOverflowNextButton(), findsOneWidget);
- expect(findOverflowBackButton(), findsOneWidget);
-
- // Tapping the overflow next button again does nothing because it is
- // disabled and there are no more children to display.
- await tester.tap(findOverflowNextButton());
- await tester.pumpAndSettle();
- expect(find.byType(TestBox), findsNWidgets(1));
- expect(findOverflowNextButton(), findsOneWidget);
+ expect(findOverflowNextButton(), findsNothing);
expect(findOverflowBackButton(), findsOneWidget);
// Tap the overflow back button to go back to the first page.
- await tester.tap(findOverflowBackButton());
+ await tester.tapAt(tester.getCenter(findOverflowBackButton()));
await tester.pumpAndSettle();
expect(find.byType(TestBox), findsNWidgets(7));
expect(findOverflowNextButton(), findsOneWidget);
@@ -157,7 +208,7 @@
expect(findOverflowBackButton(), findsNothing);
// Tap the overflow next button to show the second page of children.
- await tester.tap(findOverflowNextButton());
+ await tester.tapAt(tester.getCenter(findOverflowNextButton()));
await tester.pumpAndSettle();
// With the back button, only six children fit on this page.
expect(find.byType(TestBox), findsNWidgets(6));
@@ -165,21 +216,21 @@
expect(findOverflowBackButton(), findsOneWidget);
// Tap the overflow next button again to show the third page of children.
- await tester.tap(findOverflowNextButton());
+ await tester.tapAt(tester.getCenter(findOverflowNextButton()));
await tester.pumpAndSettle();
expect(find.byType(TestBox), findsNWidgets(1));
- expect(findOverflowNextButton(), findsOneWidget);
+ expect(findOverflowNextButton(), findsNothing);
expect(findOverflowBackButton(), findsOneWidget);
// Tap the overflow back button to go back to the second page.
- await tester.tap(findOverflowBackButton());
+ await tester.tapAt(tester.getCenter(findOverflowBackButton()));
await tester.pumpAndSettle();
expect(find.byType(TestBox), findsNWidgets(6));
expect(findOverflowNextButton(), findsOneWidget);
expect(findOverflowBackButton(), findsOneWidget);
// Tap the overflow back button to go back to the first page.
- await tester.tap(findOverflowBackButton());
+ await tester.tapAt(tester.getCenter(findOverflowBackButton()));
await tester.pumpAndSettle();
expect(find.byType(TestBox), findsNWidgets(7));
expect(findOverflowNextButton(), findsOneWidget);
@@ -345,13 +396,12 @@
final Finder buttonFinder = find.byType(CupertinoButton);
expect(buttonFinder, findsOneWidget);
- final Finder decorationFinder = find.descendant(
+ final Finder textFinder = find.descendant(
of: find.byType(CupertinoButton),
- matching: find.byType(DecoratedBox)
+ matching: find.byType(Text)
);
- expect(decorationFinder, findsOneWidget);
- final DecoratedBox decoratedBox = tester.widget(decorationFinder);
- final BoxDecoration boxDecoration = decoratedBox.decoration as BoxDecoration;
+ expect(textFinder, findsOneWidget);
+ final Text text = tester.widget(textFinder);
// Theme brightness is preferred, otherwise MediaQuery brightness is
// used. If both are null, defaults to light.
@@ -363,10 +413,10 @@
}
expect(
- boxDecoration.color!.value,
+ text.style!.color!.value,
effectiveBrightness == Brightness.dark
- ? _kToolbarBackgroundColor.darkColor.value
- : _kToolbarBackgroundColor.color.value,
+ ? _kToolbarTextColor.darkColor.value
+ : _kToolbarTextColor.color.value,
);
}, skip: kIsWeb); // [intended] We do not use Flutter-rendered context menu on the Web.
}
@@ -419,7 +469,7 @@
of: find.byType(CupertinoTextSelectionToolbar),
matching: find.byType(DecoratedBox),
);
- expect(finder, findsNWidgets(2));
+ expect(finder, findsOneWidget);
DecoratedBox decoratedBox = tester.widget(finder.first);
BoxDecoration boxDecoration = decoratedBox.decoration as BoxDecoration;
List<BoxShadow>? shadows = boxDecoration.boxShadow;
diff --git a/packages/flutter/test/foundation/annotations_test.dart b/packages/flutter/test/foundation/annotations_test.dart
new file mode 100644
index 0000000..9ac272e
--- /dev/null
+++ b/packages/flutter/test/foundation/annotations_test.dart
@@ -0,0 +1,27 @@
+// Copyright 2014 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'package:flutter/foundation.dart';
+import 'package:flutter_test/flutter_test.dart';
+
+void main() {
+ test('test Category constructor', () {
+ const List<String> sections = <String>[
+ 'First section',
+ 'Second section',
+ 'Third section'
+ ];
+ const Category category = Category(sections);
+ expect(category.sections, sections);
+ });
+ test('test DocumentationIcon constructor', () {
+ const DocumentationIcon docIcon = DocumentationIcon('Test String');
+ expect(docIcon.url, contains('Test String'));
+ });
+
+ test('test Summary constructor', () {
+ const Summary summary = Summary('Test String');
+ expect(summary.text, contains('Test String'));
+ });
+}
diff --git a/packages/flutter/test/foundation/isolates_test.dart b/packages/flutter/test/foundation/isolates_test.dart
index 571d9a1..24b834b 100644
--- a/packages/flutter/test/foundation/isolates_test.dart
+++ b/packages/flutter/test/foundation/isolates_test.dart
@@ -139,6 +139,7 @@
Future<int> computeInvalidInstanceMethod(int square) {
final ComputeTestSubject subject = ComputeTestSubject(square, ReceivePort());
+ expect(subject.additional, isA<ReceivePort>());
return compute(subject.method, square);
}
diff --git a/packages/flutter/test/foundation/leak_tracking.dart b/packages/flutter/test/foundation/leak_tracking.dart
index 26a3dbd..37b169c 100644
--- a/packages/flutter/test/foundation/leak_tracking.dart
+++ b/packages/flutter/test/foundation/leak_tracking.dart
@@ -54,13 +54,13 @@
bool semanticsEnabled = true,
TestVariant<Object?> variant = const DefaultTestVariant(),
dynamic tags,
- LeakTrackingTestConfig leakTrackingConfig = const LeakTrackingTestConfig(),
+ LeakTrackingTestConfig leakTrackingTestConfig = const LeakTrackingTestConfig(),
}) {
Future<void> wrappedCallback(WidgetTester tester) async {
await _withFlutterLeakTracking(
() async => callback(tester),
tester,
- leakTrackingConfig,
+ leakTrackingTestConfig,
);
}
@@ -169,12 +169,6 @@
/// Returns true if [leak] should be reported as failure.
bool _shouldReportLeak(LeakType leakType, LeakReport leak, Map<(String, LeakType), int> countByClassAndType) {
- // Tracking for non-GCed is temporarily disabled.
- // TODO(polina-c): turn on tracking for non-GCed after investigating existing leaks.
- if (leakType != LeakType.notDisposed) {
- return false;
- }
-
final String leakingClass = leak.type;
final (String, LeakType) classAndType = (leakingClass, leakType);
diff --git a/packages/flutter/test/foundation/leak_tracking_test.dart b/packages/flutter/test/foundation/leak_tracking_test.dart
index fc71814..e9a6648 100644
--- a/packages/flutter/test/foundation/leak_tracking_test.dart
+++ b/packages/flutter/test/foundation/leak_tracking_test.dart
@@ -18,7 +18,7 @@
});
Future<void> main() async {
- test('Trivial $LeakCleaner returns only non-disposed leaks.', () {
+ test('Trivial $LeakCleaner returns all leaks.', () {
final LeakCleaner leakCleaner = LeakCleaner(const LeakTrackingTestConfig());
final Leaks leaks = _leaksOfAllTypes();
final int leakTotal = leaks.total;
@@ -26,7 +26,7 @@
final Leaks cleanedLeaks = leakCleaner.clean(leaks);
expect(leaks.total, leakTotal);
- expect(cleanedLeaks.total, 1);
+ expect(cleanedLeaks.total, 3);
});
test('$LeakCleaner catches extra leaks', () {
@@ -48,7 +48,7 @@
(WidgetTester tester) async {
await tester.pumpWidget(_StatelessLeakingWidget());
},
- leakTrackingConfig: LeakTrackingTestConfig(
+ leakTrackingTestConfig: LeakTrackingTestConfig(
notDisposedAllowList: <String, int?>{_leakTrackedClassName: null},
notGCedAllowList: <String, int?>{_leakTrackedClassName: null},
),
@@ -59,7 +59,7 @@
(WidgetTester tester) async {
await tester.pumpWidget(_StatelessLeakingWidget());
},
- leakTrackingConfig: LeakTrackingTestConfig(
+ leakTrackingTestConfig: LeakTrackingTestConfig(
notDisposedAllowList: <String, int?>{_leakTrackedClassName: 1},
notGCedAllowList: <String, int?>{_leakTrackedClassName: 1},
),
@@ -76,7 +76,7 @@
await tester.pumpWidget(_StatelessLeakingWidget());
await tester.pumpWidget(_StatelessLeakingWidget());
},
- leakTrackingConfig: LeakTrackingTestConfig(
+ leakTrackingTestConfig: LeakTrackingTestConfig(
onLeaks: (Leaks theLeaks) {
leaks = theLeaks;
},
@@ -85,7 +85,7 @@
),
);
- tearDown(() => _verifyLeaks(leaks, expectedNotDisposed: 2));
+ tearDown(() => _verifyLeaks(leaks, expectedNotDisposed: 2, expectedNotGCed: 2, shouldContainDebugInfo: false));
});
group('respects notGCed allow lists', () {
@@ -98,7 +98,7 @@
(WidgetTester tester) async {
await tester.pumpWidget(_StatelessLeakingWidget());
},
- leakTrackingConfig: LeakTrackingTestConfig(
+ leakTrackingTestConfig: LeakTrackingTestConfig(
onLeaks: (Leaks theLeaks) {
leaks = theLeaks;
},
@@ -107,7 +107,7 @@
),
);
- tearDown(() => _verifyLeaks(leaks, expectedNotDisposed: 1));
+ tearDown(() => _verifyLeaks(leaks, expectedNotDisposed: 1, shouldContainDebugInfo: false));
});
group('catches that', () {
@@ -120,7 +120,7 @@
(WidgetTester tester) async {
await tester.pumpWidget(_StatelessLeakingWidget());
},
- leakTrackingConfig: LeakTrackingTestConfig(
+ leakTrackingTestConfig: LeakTrackingTestConfig(
onLeaks: (Leaks theLeaks) {
leaks = theLeaks;
},
@@ -128,7 +128,7 @@
),
);
- tearDown(() => _verifyLeaks(leaks, expectedNotDisposed: 1));
+ tearDown(() => _verifyLeaks(leaks, expectedNotDisposed: 1, expectedNotGCed: 1, shouldContainDebugInfo: false));
});
},
skip: isBrowser); // [intended] Leak detection is off for web.
@@ -140,7 +140,12 @@
}
/// Verifies [leaks] contains expected number of leaks for [_LeakTrackedClass].
-void _verifyLeaks(Leaks leaks, { int expectedNotDisposed = 0, int expectedNotGCed = 0 }) {
+void _verifyLeaks(
+ Leaks leaks, {
+ int expectedNotDisposed = 0,
+ int expectedNotGCed = 0,
+ required bool shouldContainDebugInfo,
+}) {
const String linkToLeakTracker = 'https://github.com/dart-lang/leak_tracker';
expect(
@@ -152,14 +157,20 @@
),
);
- _verifyLeakList(leaks.notDisposed, expectedNotDisposed);
- _verifyLeakList(leaks.notGCed, expectedNotGCed);
+ _verifyLeakList(leaks.notDisposed, expectedNotDisposed, shouldContainDebugInfo);
+ _verifyLeakList(leaks.notGCed, expectedNotGCed, shouldContainDebugInfo);
}
-void _verifyLeakList(List<LeakReport> list, int expectedCount){
+void _verifyLeakList(List<LeakReport> list, int expectedCount, bool shouldContainDebugInfo){
expect(list.length, expectedCount);
for (final LeakReport leak in list) {
+ if (shouldContainDebugInfo) {
+ expect(leak.context, isNotEmpty);
+ } else {
+ expect(leak.context ?? <String, dynamic>{}, isEmpty);
+ }
+
expect(leak.trackedClass, contains(_LeakTrackedClass.library));
expect(leak.trackedClass, contains(_leakTrackedClassName));
}
diff --git a/packages/flutter/test/foundation/timeline_test.dart b/packages/flutter/test/foundation/timeline_test.dart
new file mode 100644
index 0000000..80c95d1
--- /dev/null
+++ b/packages/flutter/test/foundation/timeline_test.dart
@@ -0,0 +1,143 @@
+// Copyright 2014 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'package:flutter/foundation.dart';
+import 'package:flutter_test/flutter_test.dart';
+
+// IMPORTANT: keep this in sync with the same constant defined
+// in foundation/timeline.dart
+const int kSliceSize = 500;
+
+void main() {
+ setUp(() {
+ FlutterTimeline.debugReset();
+ FlutterTimeline.debugCollectionEnabled = false;
+ });
+
+ test('Does not collect when collection not enabled', () {
+ FlutterTimeline.startSync('TEST');
+ FlutterTimeline.finishSync();
+ expect(
+ () => FlutterTimeline.debugCollect(),
+ throwsStateError,
+ );
+ });
+
+ test('Collects when collection is enabled', () {
+ FlutterTimeline.debugCollectionEnabled = true;
+ FlutterTimeline.startSync('TEST');
+ FlutterTimeline.finishSync();
+ final AggregatedTimings data = FlutterTimeline.debugCollect();
+ expect(data.timedBlocks, hasLength(1));
+ expect(data.aggregatedBlocks, hasLength(1));
+
+ final AggregatedTimedBlock block = data.getAggregated('TEST');
+ expect(block.name, 'TEST');
+ expect(block.count, 1);
+
+ // After collection the timeline is reset back to empty.
+ final AggregatedTimings data2 = FlutterTimeline.debugCollect();
+ expect(data2.timedBlocks, isEmpty);
+ expect(data2.aggregatedBlocks, isEmpty);
+ });
+
+ test('Deletes old data when reset', () {
+ FlutterTimeline.debugCollectionEnabled = true;
+ FlutterTimeline.startSync('TEST');
+ FlutterTimeline.finishSync();
+ FlutterTimeline.debugReset();
+
+ final AggregatedTimings data = FlutterTimeline.debugCollect();
+ expect(data.timedBlocks, isEmpty);
+ expect(data.aggregatedBlocks, isEmpty);
+ });
+
+ test('Reports zero aggregation when requested missing block', () {
+ FlutterTimeline.debugCollectionEnabled = true;
+
+ final AggregatedTimings data = FlutterTimeline.debugCollect();
+ final AggregatedTimedBlock block = data.getAggregated('MISSING');
+ expect(block.name, 'MISSING');
+ expect(block.count, 0);
+ expect(block.duration, 0);
+ });
+
+ test('Measures the runtime of a function', () {
+ FlutterTimeline.debugCollectionEnabled = true;
+
+ // The off-by-one values for `start` and `end` are for web's sake where
+ // timer values are reported as float64 and toInt/toDouble conversions
+ // are noops, so there's no value truncation happening, which makes it
+ // a bit inconsistent with Stopwatch.
+ final int start = FlutterTimeline.now - 1;
+ FlutterTimeline.timeSync('TEST', () {
+ final Stopwatch watch = Stopwatch()..start();
+ while (watch.elapsedMilliseconds < 5) {}
+ watch.stop();
+ });
+ final int end = FlutterTimeline.now + 1;
+
+ final AggregatedTimings data = FlutterTimeline.debugCollect();
+ expect(data.timedBlocks, hasLength(1));
+ expect(data.aggregatedBlocks, hasLength(1));
+
+ final TimedBlock block = data.timedBlocks.single;
+ expect(block.name, 'TEST');
+ expect(block.start, greaterThanOrEqualTo(start));
+ expect(block.end, lessThanOrEqualTo(end));
+ expect(block.duration, greaterThan(0));
+
+ final AggregatedTimedBlock aggregated = data.getAggregated('TEST');
+ expect(aggregated.name, 'TEST');
+ expect(aggregated.count, 1);
+ expect(aggregated.duration, block.duration);
+ });
+
+ test('FlutterTimeline.instanceSync does not collect anything', () {
+ FlutterTimeline.debugCollectionEnabled = true;
+ FlutterTimeline.instantSync('TEST');
+
+ final AggregatedTimings data = FlutterTimeline.debugCollect();
+ expect(data.timedBlocks, isEmpty);
+ expect(data.aggregatedBlocks, isEmpty);
+ });
+
+ test('FlutterTimeline.now returns a value', () {
+ FlutterTimeline.debugCollectionEnabled = true;
+ expect(FlutterTimeline.now, isNotNull);
+ });
+
+ test('Can collect more than one slice of data', () {
+ FlutterTimeline.debugCollectionEnabled = true;
+
+ for (int i = 0; i < 10 * kSliceSize; i++) {
+ FlutterTimeline.startSync('TEST');
+ FlutterTimeline.finishSync();
+ }
+ final AggregatedTimings data = FlutterTimeline.debugCollect();
+ expect(data.timedBlocks, hasLength(10 * kSliceSize));
+ expect(data.aggregatedBlocks, hasLength(1));
+
+ final AggregatedTimedBlock block = data.getAggregated('TEST');
+ expect(block.name, 'TEST');
+ expect(block.count, 10 * kSliceSize);
+ });
+
+ test('Collects blocks in a correct order', () {
+ FlutterTimeline.debugCollectionEnabled = true;
+ const int testCount = 7 * kSliceSize ~/ 2;
+
+ for (int i = 0; i < testCount; i++) {
+ FlutterTimeline.startSync('TEST$i');
+ FlutterTimeline.finishSync();
+ }
+
+ final AggregatedTimings data = FlutterTimeline.debugCollect();
+ expect(data.timedBlocks, hasLength(testCount));
+ expect(
+ data.timedBlocks.map<String>((TimedBlock block) => block.name).toList(),
+ List<String>.generate(testCount, (int i) => 'TEST$i'),
+ );
+ });
+}
diff --git a/packages/flutter/test/gestures/long_press_test.dart b/packages/flutter/test/gestures/long_press_test.dart
index 4de0cb4..c967956 100644
--- a/packages/flutter/test/gestures/long_press_test.dart
+++ b/packages/flutter/test/gestures/long_press_test.dart
@@ -458,7 +458,7 @@
expect(recognized, <String>['end']);
});
- testGesture('Should cancel long press when buttons change after acceptance', (GestureTester tester) {
+ testGesture('Should not cancel long press when buttons change after acceptance', (GestureTester tester) {
// First press
gesture.addPointer(down);
tester.closeArena(down.pointer);
@@ -470,7 +470,7 @@
tester.route(moveR);
expect(recognized, <String>[]);
tester.route(up);
- expect(recognized, <String>[]);
+ expect(recognized, <String>['end']);
});
testGesture('Buttons change after acceptance should not prevent the next long press', (GestureTester tester) {
@@ -701,4 +701,95 @@
longPress.dispose();
recognized.clear();
});
+
+ testGesture('Switching buttons mid-stream does not fail to send "end" event', (GestureTester tester) {
+ final List<String> recognized = <String>[];
+ final LongPressGestureRecognizer longPress = LongPressGestureRecognizer()
+ ..onLongPressStart = (LongPressStartDetails details) {
+ recognized.add('primaryStart');
+ }
+ ..onLongPressEnd = (LongPressEndDetails details) {
+ recognized.add('primaryEnd');
+ };
+
+ const PointerDownEvent down4 = PointerDownEvent(
+ pointer: 8,
+ position: Offset(10, 10),
+ );
+
+ const PointerMoveEvent move4 = PointerMoveEvent(
+ pointer: 8,
+ position: Offset(100, 200),
+ buttons: kPrimaryButton | kSecondaryButton,
+ );
+
+ const PointerUpEvent up4 = PointerUpEvent(
+ pointer: 8,
+ position: Offset(100, 200),
+ buttons: kSecondaryButton,
+ );
+
+ longPress.addPointer(down4);
+ tester.closeArena(4);
+ tester.route(down4);
+ tester.async.elapse(const Duration(milliseconds: 1000));
+ recognized.add('two seconds later...');
+ tester.route(move4);
+ tester.async.elapse(const Duration(milliseconds: 1000));
+ recognized.add('two more seconds later...');
+ tester.route(up4);
+ tester.async.elapse(const Duration(milliseconds: 1000));
+ expect(recognized, <String>['primaryStart', 'two seconds later...', 'two more seconds later...', 'primaryEnd']);
+ longPress.dispose();
+ });
+
+ testGesture('Switching buttons mid-stream does not fail to send "end" event (alternative sequence)', (GestureTester tester) {
+ // This reproduces sequences seen on macOS.
+ final List<String> recognized = <String>[];
+ final LongPressGestureRecognizer longPress = LongPressGestureRecognizer()
+ ..onLongPressStart = (LongPressStartDetails details) {
+ recognized.add('primaryStart');
+ }
+ ..onLongPressEnd = (LongPressEndDetails details) {
+ recognized.add('primaryEnd');
+ };
+
+ const PointerDownEvent down5 = PointerDownEvent(
+ pointer: 9,
+ position: Offset(10, 10),
+ );
+
+ const PointerMoveEvent move5a = PointerMoveEvent(
+ pointer: 9,
+ position: Offset(100, 200),
+ buttons: 3, // add 2
+ );
+
+ const PointerMoveEvent move5b = PointerMoveEvent(
+ pointer: 9,
+ position: Offset(100, 200),
+ buttons: 2, // remove 1
+ );
+
+ const PointerUpEvent up5 = PointerUpEvent(
+ pointer: 9,
+ position: Offset(100, 200),
+ );
+
+ longPress.addPointer(down5);
+ tester.closeArena(4);
+ tester.route(down5);
+ tester.async.elapse(const Duration(milliseconds: 1000));
+ recognized.add('two seconds later...');
+ tester.route(move5a);
+ tester.async.elapse(const Duration(milliseconds: 1000));
+ recognized.add('two more seconds later...');
+ tester.route(move5b);
+ tester.async.elapse(const Duration(milliseconds: 1000));
+ recognized.add('two more seconds later still...');
+ tester.route(up5);
+ tester.async.elapse(const Duration(milliseconds: 1000));
+ expect(recognized, <String>['primaryStart', 'two seconds later...', 'two more seconds later...', 'two more seconds later still...', 'primaryEnd']);
+ longPress.dispose();
+ });
}
diff --git a/packages/flutter/test/material/about_test.dart b/packages/flutter/test/material/about_test.dart
index 29cfdf5..3c15de4 100644
--- a/packages/flutter/test/material/about_test.dart
+++ b/packages/flutter/test/material/about_test.dart
@@ -201,7 +201,15 @@
await tester.tap(find.text('Another package'));
await tester.pumpAndSettle();
expect(find.text('Another license'), findsOneWidget);
- });
+ },
+ leakTrackingTestConfig: const LeakTrackingTestConfig(
+ // TODO(polina-c): remove after fixing
+ // https://github.com/flutter/flutter/issues/130354
+ notGCedAllowList: <String, int?>{
+ 'ValueNotifier<_OverlayEntryWidgetState?>':2,
+ 'ValueNotifier<String?>': 1,
+ },
+ ));
testWidgetsWithLeakTracking('LicensePage control test with all properties', (WidgetTester tester) async {
const FlutterLogo logo = FlutterLogo();
@@ -278,7 +286,15 @@
await tester.tap(find.text('Another package'));
await tester.pumpAndSettle();
expect(find.text('Another license'), findsOneWidget);
- });
+ },
+ leakTrackingTestConfig: const LeakTrackingTestConfig(
+ // TODO(polina-c): remove after fixing
+ // https://github.com/flutter/flutter/issues/130354
+ notGCedAllowList: <String, int?>{
+ 'ValueNotifier<_OverlayEntryWidgetState?>':2,
+ 'ValueNotifier<String?>': 1,
+ },
+ ));
testWidgetsWithLeakTracking('_PackageLicensePage title style without AppBarTheme', (WidgetTester tester) async {
LicenseRegistry.addLicense(() {
diff --git a/packages/flutter/test/material/action_chip_test.dart b/packages/flutter/test/material/action_chip_test.dart
index 92e0c1a..f3f4d67 100644
--- a/packages/flutter/test/material/action_chip_test.dart
+++ b/packages/flutter/test/material/action_chip_test.dart
@@ -6,6 +6,7 @@
import 'package:flutter_test/flutter_test.dart';
import '../foundation/leak_tracking.dart';
+import '../rendering/mock_canvas.dart';
/// Adds the basic requirements for a Chip.
Widget wrapForChip({
@@ -13,9 +14,10 @@
TextDirection textDirection = TextDirection.ltr,
double textScaleFactor = 1.0,
Brightness brightness = Brightness.light,
+ bool? useMaterial3,
}) {
return MaterialApp(
- theme: ThemeData(brightness: brightness),
+ theme: ThemeData(brightness: brightness, useMaterial3: useMaterial3),
home: Directionality(
textDirection: textDirection,
child: MediaQuery(
@@ -26,6 +28,15 @@
);
}
+RenderBox getMaterialBox(WidgetTester tester, Finder type) {
+ return tester.firstRenderObject<RenderBox>(
+ find.descendant(
+ of: type,
+ matching: find.byType(CustomPaint),
+ ),
+ );
+}
+
Material getMaterial(WidgetTester tester) {
return tester.widget<Material>(
find.descendant(
@@ -196,6 +207,120 @@
expect(decoration.color, theme.colorScheme.onSurface.withOpacity(0.12));
});
+ testWidgets('ActionChip.color resolves material states', (WidgetTester tester) async {
+ const Color disabledColor = Color(0xff00ff00);
+ const Color backgroundColor = Color(0xff0000ff);
+ final MaterialStateProperty<Color?> color = MaterialStateProperty.resolveWith((Set<MaterialState> states) {
+ if (states.contains(MaterialState.disabled)) {
+ return disabledColor;
+ }
+ return backgroundColor;
+ });
+ Widget buildApp({ required bool enabled, required bool selected }) {
+ return wrapForChip(
+ useMaterial3: true,
+ child: Column(
+ children: <Widget>[
+ ActionChip(
+ onPressed: enabled ? () { } : null,
+ color: color,
+ label: const Text('ActionChip'),
+ ),
+ ActionChip.elevated(
+ onPressed: enabled ? () { } : null,
+ color: color,
+ label: const Text('ActionChip.elevated'),
+ ),
+ ],
+ ),
+ );
+ }
+
+ // Test enabled state.
+ await tester.pumpWidget(buildApp(enabled: true, selected: false));
+
+ // Enabled ActionChip should have the provided backgroundColor.
+ expect(
+ getMaterialBox(tester, find.byType(RawChip).first),
+ paints..rrect(color: backgroundColor),
+ );
+ // Enabled elevated ActionChip should have the provided backgroundColor.
+ expect(
+ getMaterialBox(tester, find.byType(RawChip).last),
+ paints..rrect(color: backgroundColor),
+ );
+
+ // Test disabled state.
+ await tester.pumpWidget(buildApp(enabled: false, selected: false));
+ await tester.pumpAndSettle();
+
+ // Disabled ActionChip should have the provided disabledColor.
+ expect(
+ getMaterialBox(tester, find.byType(RawChip).first),
+ paints..rrect(color: disabledColor),
+ );
+ // Disabled elevated ActionChip should have the provided disabledColor.
+ expect(
+ getMaterialBox(tester, find.byType(RawChip).last),
+ paints..rrect(color: disabledColor),
+ );
+ });
+
+ testWidgets('ActionChip uses provided state color properties', (WidgetTester tester) async {
+ const Color disabledColor = Color(0xff00ff00);
+ const Color backgroundColor = Color(0xff0000ff);
+ Widget buildApp({ required bool enabled, required bool selected }) {
+ return wrapForChip(
+ useMaterial3: true,
+ child: Column(
+ children: <Widget>[
+ ActionChip(
+ onPressed: enabled ? () { } : null,
+ disabledColor: disabledColor,
+ backgroundColor: backgroundColor,
+ label: const Text('ActionChip'),
+ ),
+ ActionChip.elevated(
+ onPressed: enabled ? () { } : null,
+ disabledColor: disabledColor,
+ backgroundColor: backgroundColor,
+ label: const Text('ActionChip.elevated'),
+ ),
+ ],
+ ),
+ );
+ }
+
+ // Test enabled state.
+ await tester.pumpWidget(buildApp(enabled: true, selected: false));
+
+ // Enabled ActionChip should have the provided backgroundColor.
+ expect(
+ getMaterialBox(tester, find.byType(RawChip).first),
+ paints..rrect(color: backgroundColor),
+ );
+ // Enabled elevated ActionChip should have the provided backgroundColor.
+ expect(
+ getMaterialBox(tester, find.byType(RawChip).last),
+ paints..rrect(color: backgroundColor),
+ );
+
+ // Test disabled state.
+ await tester.pumpWidget(buildApp(enabled: false, selected: false));
+ await tester.pumpAndSettle();
+
+ // Disabled ActionChip should have the provided disabledColor.
+ expect(
+ getMaterialBox(tester, find.byType(RawChip).first),
+ paints..rrect(color: disabledColor),
+ );
+ // Disabled elevated ActionChip should have the provided disabledColor.
+ expect(
+ getMaterialBox(tester, find.byType(RawChip).last),
+ paints..rrect(color: disabledColor),
+ );
+ });
+
testWidgetsWithLeakTracking('ActionChip can be tapped', (WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
diff --git a/packages/flutter/test/material/adaptive_text_selection_toolbar_test.dart b/packages/flutter/test/material/adaptive_text_selection_toolbar_test.dart
index 8238e05..3d85f3e 100644
--- a/packages/flutter/test/material/adaptive_text_selection_toolbar_test.dart
+++ b/packages/flutter/test/material/adaptive_text_selection_toolbar_test.dart
@@ -11,6 +11,7 @@
import '../foundation/leak_tracking.dart';
import '../widgets/clipboard_utils.dart';
import '../widgets/editable_text_utils.dart';
+import '../widgets/live_text_utils.dart';
void main() {
final MockClipboard mockClipboard = MockClipboard();
@@ -184,6 +185,7 @@
onCut: () {},
onPaste: () {},
onSelectAll: () {},
+ onLiveTextInput: () {},
),
),
),
@@ -199,17 +201,18 @@
case TargetPlatform.android:
case TargetPlatform.fuchsia:
expect(find.text('Select all'), findsOneWidget);
- expect(find.byType(TextSelectionToolbarTextButton), findsNWidgets(4));
+ expect(find.byType(TextSelectionToolbarTextButton), findsNWidgets(5));
case TargetPlatform.iOS:
expect(find.text('Select All'), findsOneWidget);
- expect(find.byType(CupertinoTextSelectionToolbarButton), findsNWidgets(4));
+ expect(findLiveTextButton(), findsOneWidget);
+ expect(find.byType(CupertinoTextSelectionToolbarButton), findsNWidgets(5));
case TargetPlatform.linux:
case TargetPlatform.windows:
expect(find.text('Select all'), findsOneWidget);
- expect(find.byType(DesktopTextSelectionToolbarButton), findsNWidgets(4));
+ expect(find.byType(DesktopTextSelectionToolbarButton), findsNWidgets(5));
case TargetPlatform.macOS:
expect(find.text('Select All'), findsOneWidget);
- expect(find.byType(CupertinoDesktopTextSelectionToolbarButton), findsNWidgets(4));
+ expect(find.byType(CupertinoDesktopTextSelectionToolbarButton), findsNWidgets(5));
}
},
skip: kIsWeb, // [intended] on web the browser handles the context menu.
diff --git a/packages/flutter/test/material/autocomplete_test.dart b/packages/flutter/test/material/autocomplete_test.dart
index ad33efd..45f028b 100644
--- a/packages/flutter/test/material/autocomplete_test.dart
+++ b/packages/flutter/test/material/autocomplete_test.dart
@@ -507,4 +507,53 @@
checkOptionHighlight(tester, 'lemur', null);
checkOptionHighlight(tester, 'northern white rhinoceros', null);
});
+
+ group('optionsViewOpenDirection', () {
+ testWidgets('default (down)', (WidgetTester tester) async {
+ await tester.pumpWidget(
+ MaterialApp(
+ home: Scaffold(
+ body: Autocomplete<String>(
+ optionsBuilder: (TextEditingValue textEditingValue) => <String>['a'],
+ ),
+ ),
+ ),
+ );
+ final OptionsViewOpenDirection actual = tester.widget<RawAutocomplete<String>>(find.byType(RawAutocomplete<String>))
+ .optionsViewOpenDirection;
+ expect(actual, equals(OptionsViewOpenDirection.down));
+ });
+
+ testWidgets('down', (WidgetTester tester) async {
+ await tester.pumpWidget(
+ MaterialApp(
+ home: Scaffold(
+ body: Autocomplete<String>(
+ optionsViewOpenDirection: OptionsViewOpenDirection.down, // ignore: avoid_redundant_argument_values
+ optionsBuilder: (TextEditingValue textEditingValue) => <String>['a'],
+ ),
+ ),
+ ),
+ );
+ final OptionsViewOpenDirection actual = tester.widget<RawAutocomplete<String>>(find.byType(RawAutocomplete<String>))
+ .optionsViewOpenDirection;
+ expect(actual, equals(OptionsViewOpenDirection.down));
+ });
+
+ testWidgets('up', (WidgetTester tester) async {
+ await tester.pumpWidget(
+ MaterialApp(
+ home: Scaffold(
+ body: Autocomplete<String>(
+ optionsViewOpenDirection: OptionsViewOpenDirection.up,
+ optionsBuilder: (TextEditingValue textEditingValue) => <String>['a'],
+ ),
+ ),
+ ),
+ );
+ final OptionsViewOpenDirection actual = tester.widget<RawAutocomplete<String>>(find.byType(RawAutocomplete<String>))
+ .optionsViewOpenDirection;
+ expect(actual, equals(OptionsViewOpenDirection.up));
+ });
+ });
}
diff --git a/packages/flutter/test/material/calendar_date_picker_test.dart b/packages/flutter/test/material/calendar_date_picker_test.dart
index 971b227..038302d 100644
--- a/packages/flutter/test/material/calendar_date_picker_test.dart
+++ b/packages/flutter/test/material/calendar_date_picker_test.dart
@@ -688,152 +688,182 @@
// Day grid.
expect(tester.getSemantics(find.text('1')), matchesSemantics(
label: '1, Friday, January 1, 2016',
+ isButton: true,
hasTapAction: true,
isFocusable: true,
));
expect(tester.getSemantics(find.text('2')), matchesSemantics(
label: '2, Saturday, January 2, 2016',
+ isButton: true,
hasTapAction: true,
isFocusable: true,
));
expect(tester.getSemantics(find.text('3')), matchesSemantics(
label: '3, Sunday, January 3, 2016, Today',
+ isButton: true,
hasTapAction: true,
isFocusable: true,
));
expect(tester.getSemantics(find.text('4')), matchesSemantics(
label: '4, Monday, January 4, 2016',
+ isButton: true,
hasTapAction: true,
isFocusable: true,
));
expect(tester.getSemantics(find.text('5')), matchesSemantics(
label: '5, Tuesday, January 5, 2016',
+ isButton: true,
hasTapAction: true,
isFocusable: true,
));
expect(tester.getSemantics(find.text('6')), matchesSemantics(
label: '6, Wednesday, January 6, 2016',
+ isButton: true,
hasTapAction: true,
isFocusable: true,
));
expect(tester.getSemantics(find.text('7')), matchesSemantics(
label: '7, Thursday, January 7, 2016',
+ isButton: true,
hasTapAction: true,
isFocusable: true,
));
expect(tester.getSemantics(find.text('8')), matchesSemantics(
label: '8, Friday, January 8, 2016',
+ isButton: true,
hasTapAction: true,
isFocusable: true,
));
expect(tester.getSemantics(find.text('9')), matchesSemantics(
label: '9, Saturday, January 9, 2016',
+ isButton: true,
hasTapAction: true,
isFocusable: true,
));
expect(tester.getSemantics(find.text('10')), matchesSemantics(
label: '10, Sunday, January 10, 2016',
+ isButton: true,
hasTapAction: true,
isFocusable: true,
));
expect(tester.getSemantics(find.text('11')), matchesSemantics(
label: '11, Monday, January 11, 2016',
+ isButton: true,
hasTapAction: true,
isFocusable: true,
));
expect(tester.getSemantics(find.text('12')), matchesSemantics(
label: '12, Tuesday, January 12, 2016',
+ isButton: true,
hasTapAction: true,
isFocusable: true,
));
expect(tester.getSemantics(find.text('13')), matchesSemantics(
label: '13, Wednesday, January 13, 2016',
+ isButton: true,
hasTapAction: true,
isFocusable: true,
));
expect(tester.getSemantics(find.text('14')), matchesSemantics(
label: '14, Thursday, January 14, 2016',
+ isButton: true,
hasTapAction: true,
isFocusable: true,
));
expect(tester.getSemantics(find.text('15')), matchesSemantics(
label: '15, Friday, January 15, 2016',
+ isButton: true,
hasTapAction: true,
isSelected: true,
isFocusable: true,
));
expect(tester.getSemantics(find.text('16')), matchesSemantics(
label: '16, Saturday, January 16, 2016',
+ isButton: true,
hasTapAction: true,
isFocusable: true,
));
expect(tester.getSemantics(find.text('17')), matchesSemantics(
label: '17, Sunday, January 17, 2016',
+ isButton: true,
hasTapAction: true,
isFocusable: true,
));
expect(tester.getSemantics(find.text('18')), matchesSemantics(
label: '18, Monday, January 18, 2016',
+ isButton: true,
hasTapAction: true,
isFocusable: true,
));
expect(tester.getSemantics(find.text('19')), matchesSemantics(
label: '19, Tuesday, January 19, 2016',
+ isButton: true,
hasTapAction: true,
isFocusable: true,
));
expect(tester.getSemantics(find.text('20')), matchesSemantics(
label: '20, Wednesday, January 20, 2016',
+ isButton: true,
hasTapAction: true,
isFocusable: true,
));
expect(tester.getSemantics(find.text('21')), matchesSemantics(
label: '21, Thursday, January 21, 2016',
+ isButton: true,
hasTapAction: true,
isFocusable: true,
));
expect(tester.getSemantics(find.text('22')), matchesSemantics(
label: '22, Friday, January 22, 2016',
+ isButton: true,
hasTapAction: true,
isFocusable: true,
));
expect(tester.getSemantics(find.text('23')), matchesSemantics(
label: '23, Saturday, January 23, 2016',
+ isButton: true,
hasTapAction: true,
isFocusable: true,
));
expect(tester.getSemantics(find.text('24')), matchesSemantics(
label: '24, Sunday, January 24, 2016',
+ isButton: true,
hasTapAction: true,
isFocusable: true,
));
expect(tester.getSemantics(find.text('25')), matchesSemantics(
label: '25, Monday, January 25, 2016',
+ isButton: true,
hasTapAction: true,
isFocusable: true,
));
expect(tester.getSemantics(find.text('26')), matchesSemantics(
label: '26, Tuesday, January 26, 2016',
+ isButton: true,
hasTapAction: true,
isFocusable: true,
));
expect(tester.getSemantics(find.text('27')), matchesSemantics(
label: '27, Wednesday, January 27, 2016',
+ isButton: true,
hasTapAction: true,
isFocusable: true,
));
expect(tester.getSemantics(find.text('28')), matchesSemantics(
label: '28, Thursday, January 28, 2016',
+ isButton: true,
hasTapAction: true,
isFocusable: true,
));
expect(tester.getSemantics(find.text('29')), matchesSemantics(
label: '29, Friday, January 29, 2016',
+ isButton: true,
hasTapAction: true,
isFocusable: true,
));
expect(tester.getSemantics(find.text('30')), matchesSemantics(
label: '30, Saturday, January 30, 2016',
+ isButton: true,
hasTapAction: true,
isFocusable: true,
));
diff --git a/packages/flutter/test/material/checkbox_test.dart b/packages/flutter/test/material/checkbox_test.dart
index 8a7a592..919ee8d 100644
--- a/packages/flutter/test/material/checkbox_test.dart
+++ b/packages/flutter/test/material/checkbox_test.dart
@@ -414,7 +414,8 @@
semanticsTester.dispose();
});
- testWidgets('Checkbox tristate rendering, programmatic transitions', (WidgetTester tester) async {
+ testWidgets('Material2 - Checkbox tristate rendering, programmatic transitions', (WidgetTester tester) async {
+ final ThemeData theme = ThemeData(useMaterial3: false);
Widget buildFrame(bool? checkboxValue) {
return Theme(
data: theme,
@@ -446,8 +447,8 @@
await tester.pumpAndSettle();
expect(getCheckboxRenderer(),
paints
- ..path(color: theme.useMaterial3 ? theme.colorScheme.primary : theme.colorScheme.secondary)
- ..path(color: theme.useMaterial3 ? theme.colorScheme.onPrimary : const Color(0xFFFFFFFF))
+ ..path(color: theme.colorScheme.secondary)
+ ..path(color: const Color(0xFFFFFFFF))
); // checkmark is rendered as a path
await tester.pumpWidget(buildFrame(false));
@@ -464,8 +465,8 @@
await tester.pumpAndSettle();
expect(getCheckboxRenderer(),
paints
- ..path(color: theme.useMaterial3 ? theme.colorScheme.primary : theme.colorScheme.secondary)
- ..path(color: theme.useMaterial3 ? theme.colorScheme.onPrimary : const Color(0xFFFFFFFF))
+ ..path(color: theme.colorScheme.secondary)
+ ..path(color: const Color(0xFFFFFFFF))
); // checkmark is rendered as a path
await tester.pumpWidget(buildFrame(null));
@@ -473,10 +474,69 @@
expect(getCheckboxRenderer(), paints..line()); // null is rendered as a line (a "dash")
});
- testWidgets('Checkbox color rendering', (WidgetTester tester) async {
- final ThemeData theme = ThemeData();
+ testWidgets('Material3 - Checkbox tristate rendering, programmatic transitions', (WidgetTester tester) async {
+ final ThemeData theme = ThemeData(useMaterial3: true);
+ Widget buildFrame(bool? checkboxValue) {
+ return Theme(
+ data: theme,
+ child: Material(
+ child: StatefulBuilder(
+ builder: (BuildContext context, StateSetter setState) {
+ return Checkbox(
+ tristate: true,
+ value: checkboxValue,
+ onChanged: (bool? value) { },
+ );
+ },
+ ),
+ ),
+ );
+ }
+
+ RenderBox getCheckboxRenderer() {
+ return tester.renderObject<RenderBox>(find.byType(Checkbox));
+ }
+
+ await tester.pumpWidget(buildFrame(false));
+ await tester.pumpAndSettle();
+ expect(getCheckboxRenderer(), paints..path(color: Colors.transparent)); // paint transparent border
+ expect(getCheckboxRenderer(), isNot(paints..line())); // null is rendered as a line (a "dash")
+ expect(getCheckboxRenderer(), paints..drrect()); // empty checkbox
+
+ await tester.pumpWidget(buildFrame(true));
+ await tester.pumpAndSettle();
+ expect(getCheckboxRenderer(),
+ paints
+ ..path(color: theme.colorScheme.primary)
+ ..path(color: theme.colorScheme.onPrimary)
+ ); // checkmark is rendered as a path
+
+ await tester.pumpWidget(buildFrame(false));
+ await tester.pumpAndSettle();
+ expect(getCheckboxRenderer(), paints..path(color: Colors.transparent)); // paint transparent border
+ expect(getCheckboxRenderer(), isNot(paints..line())); // null is rendered as a line (a "dash")
+ expect(getCheckboxRenderer(), paints..drrect()); // empty checkbox
+
+ await tester.pumpWidget(buildFrame(null));
+ await tester.pumpAndSettle();
+ expect(getCheckboxRenderer(), paints..line()); // null is rendered as a line (a "dash")
+
+ await tester.pumpWidget(buildFrame(true));
+ await tester.pumpAndSettle();
+ expect(getCheckboxRenderer(),
+ paints
+ ..path(color: theme.colorScheme.primary)
+ ..path(color: theme.colorScheme.onPrimary)
+ ); // checkmark is rendered as a path
+
+ await tester.pumpWidget(buildFrame(null));
+ await tester.pumpAndSettle();
+ expect(getCheckboxRenderer(), paints..line()); // null is rendered as a line (a "dash")
+ });
+
+ testWidgets('Material2 - Checkbox color rendering', (WidgetTester tester) async {
+ ThemeData theme = ThemeData(useMaterial3: false);
const Color borderColor = Color(0xff2196f3);
- const Color m3BorderColor = Color(0xFF6750A4);
Color checkColor = const Color(0xffFFFFFF);
Color activeColor;
@@ -504,24 +564,20 @@
await tester.pumpWidget(buildFrame(checkColor: checkColor));
await tester.pumpAndSettle();
- expect(getCheckboxRenderer(), paints..path(color: theme.useMaterial3 ? m3BorderColor : borderColor)..path(color: checkColor)); // paints's color is 0xFFFFFFFF (default color)
+ expect(getCheckboxRenderer(), paints..path(color: borderColor)..path(color: checkColor)); // paints's color is 0xFFFFFFFF (default color)
checkColor = const Color(0xFF000000);
await tester.pumpWidget(buildFrame(checkColor: checkColor));
await tester.pumpAndSettle();
- expect(getCheckboxRenderer(), paints..path(color: theme.useMaterial3 ? m3BorderColor : borderColor)..path(color: checkColor)); // paints's color is 0xFF000000 (params)
+ expect(getCheckboxRenderer(), paints..path(color: borderColor)..path(color: checkColor)); // paints's color is 0xFF000000 (params)
activeColor = const Color(0xFF00FF00);
- ThemeData themeData = ThemeData();
- final bool material3 = themeData.useMaterial3;
- final ColorScheme colorScheme = material3
- ? const ColorScheme.light().copyWith(primary: activeColor)
- : const ColorScheme.light().copyWith(secondary: activeColor);
- themeData = themeData.copyWith(colorScheme: colorScheme);
+ final ColorScheme colorScheme = const ColorScheme.light().copyWith(secondary: activeColor);
+ theme = theme.copyWith(colorScheme: colorScheme);
await tester.pumpWidget(buildFrame(
- themeData: themeData),
+ themeData: theme),
);
await tester.pumpAndSettle();
expect(getCheckboxRenderer(), paints..path(color: activeColor)); // paints's color is 0xFF00FF00 (theme)
@@ -530,15 +586,139 @@
await tester.pumpWidget(buildFrame(activeColor: activeColor));
await tester.pumpAndSettle();
- expect(getCheckboxRenderer(), paints..path(color: activeColor)); // paints's color is 0xFF000000 (params)
+ expect(getCheckboxRenderer(), paints..path(color: activeColor));
});
- testWidgets('Checkbox is focusable and has correct focus color', (WidgetTester tester) async {
+ testWidgets('Material3 - Checkbox color rendering', (WidgetTester tester) async {
+ ThemeData theme = ThemeData(useMaterial3: true);
+ const Color borderColor = Color(0xFF6750A4);
+ Color checkColor = const Color(0xffFFFFFF);
+ Color activeColor;
+
+ Widget buildFrame({Color? activeColor, Color? checkColor, ThemeData? themeData}) {
+ return Material(
+ child: Theme(
+ data: themeData ?? theme,
+ child: StatefulBuilder(
+ builder: (BuildContext context, StateSetter setState) {
+ return Checkbox(
+ value: true,
+ activeColor: activeColor,
+ checkColor: checkColor,
+ onChanged: (bool? value) { },
+ );
+ },
+ ),
+ ),
+ );
+ }
+
+ RenderBox getCheckboxRenderer() {
+ return tester.renderObject<RenderBox>(find.byType(Checkbox));
+ }
+
+ await tester.pumpWidget(buildFrame(checkColor: checkColor));
+ await tester.pumpAndSettle();
+ expect(getCheckboxRenderer(), paints..path(color: borderColor)..path(color: checkColor)); // paints's color is 0xFFFFFFFF (default color)
+
+ checkColor = const Color(0xFF000000);
+
+ await tester.pumpWidget(buildFrame(checkColor: checkColor));
+ await tester.pumpAndSettle();
+ expect(getCheckboxRenderer(), paints..path(color: borderColor)..path(color: checkColor)); // paints's color is 0xFF000000 (params)
+
+ activeColor = const Color(0xFF00FF00);
+
+ final ColorScheme colorScheme = const ColorScheme.light().copyWith(primary: activeColor);
+ theme = theme.copyWith(colorScheme: colorScheme);
+ await tester.pumpWidget(buildFrame(themeData: theme));
+ await tester.pumpAndSettle();
+ expect(getCheckboxRenderer(), paints..path(color: activeColor)); // paints's color is 0xFF00FF00 (theme)
+
+ activeColor = const Color(0xFF000000);
+
+ await tester.pumpWidget(buildFrame(activeColor: activeColor));
+ await tester.pumpAndSettle();
+ expect(getCheckboxRenderer(), paints..path(color: activeColor));
+ });
+
+ testWidgets('Material2 - Checkbox is focusable and has correct focus color', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(debugLabel: 'Checkbox');
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
bool? value = true;
Widget buildApp({bool enabled = true}) {
return MaterialApp(
+ theme: ThemeData(useMaterial3: false),
+ home: Material(
+ child: Center(
+ child: StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
+ return Checkbox(
+ value: value,
+ onChanged: enabled ? (bool? newValue) {
+ setState(() {
+ value = newValue;
+ });
+ } : null,
+ focusColor: Colors.orange[500],
+ autofocus: true,
+ focusNode: focusNode,
+ );
+ }),
+ ),
+ ),
+ );
+ }
+ await tester.pumpWidget(buildApp());
+
+ await tester.pumpAndSettle();
+ expect(focusNode.hasPrimaryFocus, isTrue);
+ expect(
+ Material.of(tester.element(find.byType(Checkbox))),
+ paints
+ ..circle(color: Colors.orange[500])
+ ..path(color: const Color(0xff2196f3))
+ ..path(color: Colors.white)
+ );
+
+ // Check the false value.
+ value = false;
+ await tester.pumpWidget(buildApp());
+ await tester.pumpAndSettle();
+ expect(focusNode.hasPrimaryFocus, isTrue);
+ expect(
+ Material.of(tester.element(find.byType(Checkbox))),
+ paints
+ ..circle(color: Colors.orange[500])
+ ..drrect(
+ color: const Color(0x8a000000),
+ outer: RRect.fromLTRBR(15.0, 15.0, 33.0, 33.0, const Radius.circular(1.0)),
+ inner: RRect.fromLTRBR(17.0, 17.0, 31.0, 31.0, Radius.zero),
+ ),
+ );
+
+ // Check what happens when disabled.
+ value = false;
+ await tester.pumpWidget(buildApp(enabled: false));
+ await tester.pumpAndSettle();
+ expect(focusNode.hasPrimaryFocus, isFalse);
+ expect(
+ Material.of(tester.element(find.byType(Checkbox))),
+ paints
+ ..drrect(
+ color: const Color(0x61000000),
+ outer: RRect.fromLTRBR(15.0, 15.0, 33.0, 33.0, const Radius.circular(1.0)),
+ inner: RRect.fromLTRBR(17.0, 17.0, 31.0, 31.0, Radius.zero),
+ ),
+ );
+ });
+
+ testWidgets('Material3 - Checkbox is focusable and has correct focus color', (WidgetTester tester) async {
+ final FocusNode focusNode = FocusNode(debugLabel: 'Checkbox');
+ final ThemeData theme = ThemeData(useMaterial3: true);
+ tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
+ bool? value = true;
+ Widget buildApp({bool enabled = true}) {
+ return MaterialApp(
theme: theme,
home: Material(
child: Center(
@@ -562,19 +742,13 @@
await tester.pumpWidget(buildApp());
await tester.pumpAndSettle();
- final bool material3 = theme.useMaterial3;
expect(focusNode.hasPrimaryFocus, isTrue);
expect(
Material.of(tester.element(find.byType(Checkbox))),
- material3
- ? (paints
- ..circle(color: Colors.orange[500])
- ..path(color: theme.colorScheme.primary)
- ..path(color: theme.colorScheme.onPrimary))
- : (paints
- ..circle(color: Colors.orange[500])
- ..path(color: const Color(0xff2196f3))
- ..path(color: Colors.white))
+ paints
+ ..circle(color: Colors.orange[500])
+ ..path(color: theme.colorScheme.primary)
+ ..path(color: theme.colorScheme.onPrimary)
);
// Check the false value.
@@ -587,8 +761,8 @@
paints
..circle(color: Colors.orange[500])
..drrect(
- color: material3 ? theme.colorScheme.onSurface : const Color(0x8a000000),
- outer: RRect.fromLTRBR(15.0, 15.0, 33.0, 33.0, material3 ? const Radius.circular(2.0) : const Radius.circular(1.0)),
+ color: theme.colorScheme.onSurface,
+ outer: RRect.fromLTRBR(15.0, 15.0, 33.0, 33.0, const Radius.circular(2.0)),
inner: RRect.fromLTRBR(17.0, 17.0, 31.0, 31.0, Radius.zero),
),
);
@@ -602,8 +776,8 @@
Material.of(tester.element(find.byType(Checkbox))),
paints
..drrect(
- color: material3 ? theme.colorScheme.onSurface.withOpacity(0.38) : const Color(0x61000000),
- outer: RRect.fromLTRBR(15.0, 15.0, 33.0, 33.0, material3 ? const Radius.circular(2.0) : const Radius.circular(1.0)),
+ color: theme.colorScheme.onSurface.withOpacity(0.38),
+ outer: RRect.fromLTRBR(15.0, 15.0, 33.0, 33.0, const Radius.circular(2.0)),
inner: RRect.fromLTRBR(17.0, 17.0, 31.0, 31.0, Radius.zero),
),
);
@@ -670,10 +844,10 @@
);
});
- testWidgets('Checkbox can be hovered and has correct hover color', (WidgetTester tester) async {
+ testWidgets('Material2 - Checkbox can be hovered and has correct hover color', (WidgetTester tester) async {
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
bool? value = true;
- final bool material3 = theme.useMaterial3;
+ final ThemeData theme = ThemeData(useMaterial3: false);
Widget buildApp({bool enabled = true}) {
return MaterialApp(
theme: theme,
@@ -699,8 +873,8 @@
expect(
Material.of(tester.element(find.byType(Checkbox))),
paints
- ..path(color: material3 ? const Color(0xff6750a4) : const Color(0xff2196f3))
- ..path(color: material3 ? theme.colorScheme.onPrimary : const Color(0xffffffff), style: PaintingStyle.stroke, strokeWidth: 2.0),
+ ..path(color: const Color(0xff2196f3))
+ ..path(color: const Color(0xffffffff), style: PaintingStyle.stroke, strokeWidth: 2.0),
);
// Start hovering
@@ -712,8 +886,8 @@
expect(
Material.of(tester.element(find.byType(Checkbox))),
paints
- ..path(color: material3 ? const Color(0xff6750a4) : const Color(0xff2196f3))
- ..path(color: material3 ? theme.colorScheme.onPrimary : const Color(0xffffffff), style: PaintingStyle.stroke, strokeWidth: 2.0),
+ ..path(color: const Color(0xff2196f3))
+ ..path(color: const Color(0xffffffff), style: PaintingStyle.stroke, strokeWidth: 2.0),
);
// Check what happens when disabled.
@@ -722,8 +896,65 @@
expect(
Material.of(tester.element(find.byType(Checkbox))),
paints
- ..path(color: material3 ? theme.colorScheme.onSurface.withOpacity(0.38) : const Color(0x61000000))
- ..path(color: material3 ? theme.colorScheme.surface : const Color(0xffffffff), style: PaintingStyle.stroke, strokeWidth: 2.0),
+ ..path(color: const Color(0x61000000))
+ ..path(color: const Color(0xffffffff), style: PaintingStyle.stroke, strokeWidth: 2.0),
+ );
+ });
+
+ testWidgets('Material3 - Checkbox can be hovered and has correct hover color', (WidgetTester tester) async {
+ tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
+ bool? value = true;
+ final ThemeData theme = ThemeData(useMaterial3: true);
+ Widget buildApp({bool enabled = true}) {
+ return MaterialApp(
+ theme: theme,
+ home: Material(
+ child: Center(
+ child: StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
+ return Checkbox(
+ value: value,
+ onChanged: enabled ? (bool? newValue) {
+ setState(() {
+ value = newValue;
+ });
+ } : null,
+ hoverColor: Colors.orange[500],
+ );
+ }),
+ ),
+ ),
+ );
+ }
+ await tester.pumpWidget(buildApp());
+ await tester.pumpAndSettle();
+ expect(
+ Material.of(tester.element(find.byType(Checkbox))),
+ paints
+ ..path(color: const Color(0xff6750a4))
+ ..path(color: theme.colorScheme.onPrimary, style: PaintingStyle.stroke, strokeWidth: 2.0),
+ );
+
+ // Start hovering
+ final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
+ await gesture.moveTo(tester.getCenter(find.byType(Checkbox)));
+
+ await tester.pumpWidget(buildApp());
+ await tester.pumpAndSettle();
+ expect(
+ Material.of(tester.element(find.byType(Checkbox))),
+ paints
+ ..path(color: const Color(0xff6750a4))
+ ..path(color: theme.colorScheme.onPrimary, style: PaintingStyle.stroke, strokeWidth: 2.0),
+ );
+
+ // Check what happens when disabled.
+ await tester.pumpWidget(buildApp(enabled: false));
+ await tester.pumpAndSettle();
+ expect(
+ Material.of(tester.element(find.byType(Checkbox))),
+ paints
+ ..path(color: theme.colorScheme.onSurface.withOpacity(0.38))
+ ..path(color: theme.colorScheme.surface, style: PaintingStyle.stroke, strokeWidth: 2.0),
);
});
@@ -1108,12 +1339,12 @@
);
});
- testWidgets('Checkbox default overlay color in active/pressed/focused/hovered states', (WidgetTester tester) async {
+ testWidgets('Material2 - Checkbox default overlay color in active/pressed/focused/hovered states', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(debugLabel: 'Checkbox');
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
+ final ThemeData theme = ThemeData(useMaterial3: false);
final ColorScheme colors = theme.colorScheme;
- final bool material3 = theme.useMaterial3;
Widget buildCheckbox({bool active = false, bool focused = false}) {
return MaterialApp(
theme: theme,
@@ -1134,11 +1365,8 @@
expect(
Material.of(tester.element(find.byType(Checkbox))),
- material3
- ? (paints..circle(color: colors.primary.withOpacity(0.12)))
- : (paints
- ..circle(color: theme.unselectedWidgetColor.withAlpha(kRadialReactionAlpha),)
- ),
+ paints
+ ..circle(color: theme.unselectedWidgetColor.withAlpha(kRadialReactionAlpha)),
reason: 'Default inactive pressed Checkbox should have overlay color from default fillColor',
);
@@ -1148,11 +1376,8 @@
expect(
Material.of(tester.element(find.byType(Checkbox))),
- material3
- ? (paints..circle(color: colors.onSurface.withOpacity(0.12)))
- : (paints
- ..circle(color: colors.secondary.withAlpha(kRadialReactionAlpha),)
- ),
+ paints
+ ..circle(color: colors.secondary.withAlpha(kRadialReactionAlpha)),
reason: 'Default active pressed Checkbox should have overlay color from default fillColor',
);
@@ -1163,9 +1388,7 @@
expect(focusNode.hasPrimaryFocus, isTrue);
expect(
Material.of(tester.element(find.byType(Checkbox))),
- material3
- ? (paints..circle(color: colors.onSurface.withOpacity(0.12)))
- : (paints..circle(color: theme.focusColor)),
+ paints..circle(color: theme.focusColor),
reason: 'Focused Checkbox should use default focused overlay color',
);
@@ -1178,9 +1401,72 @@
expect(
Material.of(tester.element(find.byType(Checkbox))),
- material3
- ? (paints..circle(color: colors.onSurface.withOpacity(0.08)))
- : (paints..circle(color: theme.hoverColor)),
+ paints..circle(color: theme.hoverColor),
+ reason: 'Hovered Checkbox should use default hovered overlay color',
+ );
+ });
+
+ testWidgets('Material3 - Checkbox default overlay color in active/pressed/focused/hovered states', (WidgetTester tester) async {
+ final FocusNode focusNode = FocusNode(debugLabel: 'Checkbox');
+ tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
+
+ final ThemeData theme = ThemeData(useMaterial3: true);
+ final ColorScheme colors = theme.colorScheme;
+ Widget buildCheckbox({bool active = false, bool focused = false}) {
+ return MaterialApp(
+ theme: theme,
+ home: Scaffold(
+ body: Checkbox(
+ focusNode: focusNode,
+ autofocus: focused,
+ value: active,
+ onChanged: (_) { },
+ ),
+ ),
+ );
+ }
+
+ await tester.pumpWidget(buildCheckbox());
+ await tester.startGesture(tester.getCenter(find.byType(Checkbox)));
+ await tester.pumpAndSettle();
+
+ expect(
+ Material.of(tester.element(find.byType(Checkbox))),
+ paints..circle(color: colors.primary.withOpacity(0.12)),
+ reason: 'Default inactive pressed Checkbox should have overlay color from default fillColor',
+ );
+
+ await tester.pumpWidget(buildCheckbox(active: true));
+ await tester.startGesture(tester.getCenter(find.byType(Checkbox)));
+ await tester.pumpAndSettle();
+
+ expect(
+ Material.of(tester.element(find.byType(Checkbox))),
+ paints..circle(color: colors.onSurface.withOpacity(0.12)),
+ reason: 'Default active pressed Checkbox should have overlay color from default fillColor',
+ );
+
+ await tester.pumpWidget(Container()); // reset test
+ await tester.pumpWidget(buildCheckbox(focused: true));
+ await tester.pumpAndSettle();
+
+ expect(focusNode.hasPrimaryFocus, isTrue);
+ expect(
+ Material.of(tester.element(find.byType(Checkbox))),
+ paints..circle(color: colors.onSurface.withOpacity(0.12)),
+ reason: 'Focused Checkbox should use default focused overlay color',
+ );
+
+ await tester.pumpWidget(Container()); // reset test
+ await tester.pumpWidget(buildCheckbox());
+ final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
+ await gesture.addPointer();
+ await gesture.moveTo(tester.getCenter(find.byType(Checkbox)));
+ await tester.pumpAndSettle();
+
+ expect(
+ Material.of(tester.element(find.byType(Checkbox))),
+ paints..circle(color: colors.onSurface.withOpacity(0.08)),
reason: 'Hovered Checkbox should use default hovered overlay color',
);
});
@@ -1516,13 +1802,13 @@
expect(getCheckboxRenderer(), paints..path(color: activeColor)); // checkbox fill
});
- testWidgets('Checkbox MaterialStateBorderSide applies unconditionally', (WidgetTester tester) async {
+ testWidgets('Material2 - Checkbox MaterialStateBorderSide applies unconditionally', (WidgetTester tester) async {
const Color borderColor = Color(0xfff44336);
const BorderSide side = BorderSide(
width: 4,
color: borderColor,
);
- final bool material3 = theme.useMaterial3;
+ final ThemeData theme = ThemeData(useMaterial3: false);
Widget buildApp({ bool? value, bool enabled = true }) {
return MaterialApp(
@@ -1546,7 +1832,7 @@
paints
..drrect(
color: borderColor,
- outer: material3 ? RRect.fromLTRBR(15, 15, 33, 33, const Radius.circular(2)) : RRect.fromLTRBR(15, 15, 33, 33, const Radius.circular(1)),
+ outer: RRect.fromLTRBR(15, 15, 33, 33, const Radius.circular(1)),
inner: RRect.fromLTRBR(19, 19, 29, 29, Radius.zero),
),
);
@@ -1570,6 +1856,60 @@
expectBorder();
});
+ testWidgets('Material3 - Checkbox MaterialStateBorderSide applies unconditionally', (WidgetTester tester) async {
+ const Color borderColor = Color(0xfff44336);
+ const BorderSide side = BorderSide(
+ width: 4,
+ color: borderColor,
+ );
+ final ThemeData theme = ThemeData(useMaterial3: true);
+
+ Widget buildApp({ bool? value, bool enabled = true }) {
+ return MaterialApp(
+ theme: theme,
+ home: Material(
+ child: Center(
+ child: Checkbox(
+ value: value,
+ tristate: value == null,
+ onChanged: enabled ? (bool? newValue) { } : null,
+ side: MaterialStateBorderSide.resolveWith((Set<MaterialState> states) => side),
+ ),
+ ),
+ ),
+ );
+ }
+
+ void expectBorder() {
+ expect(
+ tester.renderObject<RenderBox>(find.byType(Checkbox)),
+ paints
+ ..drrect(
+ color: borderColor,
+ outer: RRect.fromLTRBR(15, 15, 33, 33, const Radius.circular(2)),
+ inner: RRect.fromLTRBR(19, 19, 29, 29, Radius.zero),
+ ),
+ );
+ }
+
+ await tester.pumpWidget(buildApp(value: false));
+ await tester.pumpAndSettle();
+ expectBorder();
+
+
+ await tester.pumpWidget(buildApp(value: false, enabled: false));
+ await tester.pumpAndSettle();
+ expectBorder();
+
+ await tester.pumpWidget(buildApp(value: true));
+ await tester.pumpAndSettle();
+ expectBorder();
+
+ await tester.pumpWidget(buildApp());
+ await tester.pumpAndSettle();
+ expectBorder();
+ });
+
testWidgets('disabled checkbox shows tooltip', (WidgetTester tester) async {
const String longPressTooltip = 'long press tooltip';
const String tapTooltip = 'tap tooltip';
@@ -1624,7 +1964,7 @@
expect(find.text(tapTooltip), findsOneWidget);
});
- testWidgets('Checkbox has default error color when isError is set to true - M3', (WidgetTester tester) async {
+ testWidgets('Material3 - Checkbox has default error color when isError is set to true', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(debugLabel: 'Checkbox');
final ThemeData themeData = ThemeData(useMaterial3: true);
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
@@ -1696,7 +2036,7 @@
await tester.pump();
});
- testWidgets('Checkbox MaterialStateBorderSide applies in error states - M3', (WidgetTester tester) async {
+ testWidgets('Material3 - Checkbox MaterialStateBorderSide applies in error states', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(debugLabel: 'Checkbox');
final ThemeData themeData = ThemeData(useMaterial3: true);
const Color borderColor = Color(0xffffeb3b);
@@ -1775,7 +2115,7 @@
await tester.pump();
});
- testWidgets('Checkbox has correct default shape - M3', (WidgetTester tester) async {
+ testWidgets('Material3 - Checkbox has correct default shape', (WidgetTester tester) async {
final ThemeData themeData = ThemeData(useMaterial3: true);
Widget buildApp() {
@@ -1841,7 +2181,8 @@
}
});
- testWidgets('Checkbox respects fillColor when it is unchecked', (WidgetTester tester) async {
+ testWidgets('Material2 - Checkbox respects fillColor when it is unchecked', (WidgetTester tester) async {
+ final ThemeData theme = ThemeData(useMaterial3: false);
const Color activeBackgroundColor = Color(0xff123456);
const Color inactiveBackgroundColor = Color(0xff654321);
@@ -1870,14 +2211,13 @@
}
// Checkbox is unselected, so the default BorderSide appears and fillColor is checkbox's background color.
-
await tester.pumpWidget(buildApp());
await tester.pumpAndSettle();
expect(
getCheckboxRenderer(),
paints
..drrect(
- color: theme.useMaterial3 ? theme.colorScheme.onSurfaceVariant : theme.unselectedWidgetColor,
+ color: theme.unselectedWidgetColor,
),
);
expect(getCheckboxRenderer(), paints..path(color: inactiveBackgroundColor));
@@ -1888,7 +2228,60 @@
getCheckboxRenderer(),
paints
..drrect(
- color: theme.useMaterial3 ? theme.colorScheme.onSurface.withOpacity(0.38) : theme.disabledColor,
+ color: theme.disabledColor,
+ ),
+ );
+ expect(getCheckboxRenderer(), paints..path(color: inactiveBackgroundColor));
+ });
+
+ testWidgets('Material3 - Checkbox respects fillColor when it is unchecked', (WidgetTester tester) async {
+ final ThemeData theme = ThemeData(useMaterial3: true);
+ const Color activeBackgroundColor = Color(0xff123456);
+ const Color inactiveBackgroundColor = Color(0xff654321);
+
+ Widget buildApp({ bool enabled = true }) {
+ return MaterialApp(
+ theme: theme,
+ home: Material(
+ child: Center(
+ child: Checkbox(
+ fillColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
+ if (states.contains(MaterialState.selected)) {
+ return activeBackgroundColor;
+ }
+ return inactiveBackgroundColor;
+ }),
+ value: false,
+ onChanged: enabled ? (bool? newValue) { } : null,
+ ),
+ ),
+ ),
+ );
+ }
+
+ RenderBox getCheckboxRenderer() {
+ return tester.renderObject<RenderBox>(find.byType(Checkbox));
+ }
+
+ // Checkbox is unselected, so the default BorderSide appears and fillColor is checkbox's background color.
+ await tester.pumpWidget(buildApp());
+ await tester.pumpAndSettle();
+ expect(
+ getCheckboxRenderer(),
+ paints
+ ..drrect(
+ color: theme.colorScheme.onSurfaceVariant,
+ ),
+ );
+ expect(getCheckboxRenderer(), paints..path(color: inactiveBackgroundColor));
+
+ await tester.pumpWidget(buildApp(enabled: false));
+ await tester.pumpAndSettle();
+ expect(
+ getCheckboxRenderer(),
+ paints
+ ..drrect(
+ color: theme.colorScheme.onSurface.withOpacity(0.38),
),
);
expect(getCheckboxRenderer(), paints..path(color: inactiveBackgroundColor));
diff --git a/packages/flutter/test/material/chip_test.dart b/packages/flutter/test/material/chip_test.dart
index 53b54d8..baa306a 100644
--- a/packages/flutter/test/material/chip_test.dart
+++ b/packages/flutter/test/material/chip_test.dart
@@ -74,9 +74,10 @@
TextDirection textDirection = TextDirection.ltr,
double textScaleFactor = 1.0,
Brightness brightness = Brightness.light,
+ bool? useMaterial3,
}) {
return MaterialApp(
- theme: ThemeData(brightness: brightness, useMaterial3: false),
+ theme: ThemeData(brightness: brightness, useMaterial3: useMaterial3),
home: Directionality(
textDirection: textDirection,
child: MediaQuery(
@@ -142,9 +143,11 @@
String? chipTooltip,
String? deleteButtonTooltipMessage,
VoidCallback? onPressed = doNothing,
+ bool? useMaterial3,
}) {
return wrapForChip(
textDirection: textDirection,
+ useMaterial3: useMaterial3,
child: Wrap(
children: <Widget>[
RawChip(
@@ -579,6 +582,7 @@
const TextStyle style = TextStyle(fontSize: 10.0);
await tester.pumpWidget(
wrapForChip(
+ useMaterial3: false,
child: const Row(
children: <Widget>[
Chip(label: Text('Test'), labelStyle: style),
@@ -615,6 +619,7 @@
testWidgets('Chip responds to materialTapTargetSize', (WidgetTester tester) async {
await tester.pumpWidget(
wrapForChip(
+ useMaterial3: false,
child: const Column(
children: <Widget>[
Chip(
@@ -731,6 +736,7 @@
testWidgets('Chip responds to textScaleFactor', (WidgetTester tester) async {
await tester.pumpWidget(
wrapForChip(
+ useMaterial3: false,
child: const Column(
children: <Widget>[
Chip(
@@ -809,6 +815,7 @@
final Key keyB = GlobalKey();
await tester.pumpWidget(
wrapForChip(
+ useMaterial3: false,
child: Column(
children: <Widget>[
Chip(
@@ -946,6 +953,7 @@
Future<void> pushChip({ Widget? avatar }) async {
return tester.pumpWidget(
wrapForChip(
+ useMaterial3: false,
child: Wrap(
children: <Widget>[
RawChip(
@@ -1060,6 +1068,7 @@
Future<void> pushChip({ bool deletable = false }) async {
return tester.pumpWidget(
wrapForChip(
+ useMaterial3: false,
child: Wrap(
children: <Widget>[
StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
@@ -1211,6 +1220,7 @@
await tester.pumpWidget(
chipWithOptionalDeleteButton(
+ useMaterial3: false,
labelKey: labelKey,
deleteButtonKey: deleteButtonKey,
deletable: true,
@@ -1293,6 +1303,7 @@
await tester.pumpWidget(
chipWithOptionalDeleteButton(
+ useMaterial3: false,
labelKey: labelKey,
deleteButtonKey: deleteButtonKey,
deletable: true,
@@ -1346,6 +1357,7 @@
await tester.pumpWidget(
chipWithOptionalDeleteButton(
+ useMaterial3: false,
labelKey: labelKey,
onPressed: null,
deleteButtonKey: deleteButtonKey,
@@ -1430,6 +1442,7 @@
await tester.pumpWidget(
chipWithOptionalDeleteButton(
+ useMaterial3: false,
labelKey: labelKey,
deletable: false,
),
@@ -1484,6 +1497,7 @@
Future<void> pushChip({ Widget? avatar, bool selectable = false }) async {
return tester.pumpWidget(
wrapForChip(
+ useMaterial3: false,
child: Wrap(
children: <Widget>[
StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
@@ -1564,6 +1578,7 @@
Future<void> pushChip({ bool selectable = false }) async {
return tester.pumpWidget(
wrapForChip(
+ useMaterial3: false,
child: Wrap(
children: <Widget>[
StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
@@ -1637,6 +1652,7 @@
Future<void> pushChip({ Widget? avatar, bool selectable = false }) async {
return tester.pumpWidget(
wrapForChip(
+ useMaterial3: false,
child: Wrap(
children: <Widget>[
StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
@@ -2572,12 +2588,17 @@
});
testWidgets('selected chip and avatar draw darkened layer within avatar circle', (WidgetTester tester) async {
- await tester.pumpWidget(wrapForChip(child: const FilterChip(
- avatar: CircleAvatar(child: Text('t')),
- label: Text('test'),
- selected: true,
- onSelected: null,
- )));
+ await tester.pumpWidget(
+ wrapForChip(
+ useMaterial3: false,
+ child: const FilterChip(
+ avatar: CircleAvatar(child: Text('t')),
+ label: Text('test'),
+ selected: true,
+ onSelected: null,
+ ),
+ ),
+ );
final RenderBox rawChip = tester.firstRenderObject<RenderBox>(
find.descendant(
of: find.byType(RawChip),
@@ -3298,6 +3319,7 @@
const OutlinedBorder shape = ContinuousRectangleBorder();
await tester.pumpWidget(wrapForChip(
+ useMaterial3: false,
child: const RawChip(
label: Text('text'),
backgroundColor: backgroundColor,
@@ -3341,6 +3363,338 @@
..rect(color: const Color(0x1f000000)),
);
});
+
+ testWidgets('RawChip.color resolves material states', (WidgetTester tester) async {
+ const Color disabledSelectedColor = Color(0xffffff00);
+ const Color disabledColor = Color(0xff00ff00);
+ const Color backgroundColor = Color(0xff0000ff);
+ const Color selectedColor = Color(0xffff0000);
+ Widget buildApp({ required bool enabled, required bool selected }) {
+ return wrapForChip(
+ useMaterial3: true,
+ child: RawChip(
+ isEnabled: enabled,
+ selected: selected,
+ color: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
+ if (states.contains(MaterialState.disabled) && states.contains(MaterialState.selected)) {
+ return disabledSelectedColor;
+ }
+ if (states.contains(MaterialState.disabled)) {
+ return disabledColor;
+ }
+ if (states.contains(MaterialState.selected)) {
+ return selectedColor;
+ }
+ return backgroundColor;
+ }),
+ label: const Text('RawChip'),
+ ),
+ );
+ }
+
+ // Test enabled chip.
+ await tester.pumpWidget(buildApp(enabled: true, selected: false));
+
+ // Enabled chip should have the provided backgroundColor.
+ expect(getMaterialBox(tester), paints..rrect(color: backgroundColor));
+
+ // Test disabled chip.
+ await tester.pumpWidget(buildApp(enabled: false, selected: false));
+ await tester.pumpAndSettle();
+
+ // Disabled chip should have the provided disabledColor.
+ expect(getMaterialBox(tester), paints..rrect(color: disabledColor));
+
+ // Test enabled & selected chip.
+ await tester.pumpWidget(buildApp(enabled: true, selected: true));
+ await tester.pumpAndSettle();
+
+ // Enabled & selected chip should have the provided selectedColor.
+ expect(getMaterialBox(tester), paints..rrect(color: selectedColor));
+
+ // Test disabled & selected chip.
+ await tester.pumpWidget(buildApp(enabled: false, selected: true));
+ await tester.pumpAndSettle();
+
+ // Disabled & selected chip should have the provided disabledSelectedColor.
+ expect(getMaterialBox(tester), paints..rrect(color: disabledSelectedColor));
+ });
+
+ testWidgets('RawChip uses provided state color properties', (WidgetTester tester) async {
+ const Color disabledColor = Color(0xff00ff00);
+ const Color backgroundColor = Color(0xff0000ff);
+ const Color selectedColor = Color(0xffff0000);
+ Widget buildApp({ required bool enabled, required bool selected }) {
+ return wrapForChip(
+ useMaterial3: true,
+ child: RawChip(
+ isEnabled: enabled,
+ selected: selected,
+ disabledColor: disabledColor,
+ backgroundColor: backgroundColor,
+ selectedColor: selectedColor,
+ label: const Text('RawChip'),
+ ),
+ );
+ }
+
+ // Test enabled chip.
+ await tester.pumpWidget(buildApp(enabled: true, selected: false));
+
+ // Enabled chip should have the provided backgroundColor.
+ expect(getMaterialBox(tester), paints..rrect(color: backgroundColor));
+
+ // Test disabled chip.
+ await tester.pumpWidget(buildApp(enabled: false, selected: false));
+ await tester.pumpAndSettle();
+
+ // Disabled chip should have the provided disabledColor.
+ expect(getMaterialBox(tester), paints..rrect(color: disabledColor));
+
+ // Test enabled & selected chip.
+ await tester.pumpWidget(buildApp(enabled: true, selected: true));
+ await tester.pumpAndSettle();
+
+ // Enabled & selected chip should have the provided selectedColor.
+ expect(getMaterialBox(tester), paints..rrect(color: selectedColor));
+ });
+
+ group('Material 2', () {
+ // These tests are only relevant for Material 2. Once Material 2
+ // support is deprecated and the APIs are removed, these tests
+ // can be deleted.
+
+ testWidgets('M2 Chip defaults', (WidgetTester tester) async {
+ late TextTheme textTheme;
+
+ Widget buildFrame(Brightness brightness) {
+ return MaterialApp(
+ theme: ThemeData(brightness: brightness, useMaterial3: false),
+ home: Scaffold(
+ body: Center(
+ child: Builder(
+ builder: (BuildContext context) {
+ textTheme = Theme.of(context).textTheme;
+ return Chip(
+ avatar: const CircleAvatar(child: Text('A')),
+ label: const Text('Chip A'),
+ onDeleted: () { },
+ );
+ },
+ ),
+ ),
+ ),
+ );
+ }
+
+ await tester.pumpWidget(buildFrame(Brightness.light));
+ expect(getMaterialBox(tester), paints..rrect()..circle(color: const Color(0xff1976d2)));
+ expect(tester.getSize(find.byType(Chip)), const Size(156.0, 48.0));
+ expect(getMaterial(tester).color, null);
+ expect(getMaterial(tester).elevation, 0);
+ expect(getMaterial(tester).shape, const StadiumBorder());
+ expect(getIconData(tester).color?.value, 0xffffffff);
+ expect(getIconData(tester).opacity, null);
+ expect(getIconData(tester).size, null);
+
+ TextStyle labelStyle = getLabelStyle(tester, 'Chip A').style;
+ expect(labelStyle.color?.value, 0xde000000);
+ expect(labelStyle.fontFamily, textTheme.bodyLarge?.fontFamily);
+ expect(labelStyle.fontFamilyFallback, textTheme.bodyLarge?.fontFamilyFallback);
+ expect(labelStyle.fontFeatures, textTheme.bodyLarge?.fontFeatures);
+ expect(labelStyle.fontSize, textTheme.bodyLarge?.fontSize);
+ expect(labelStyle.fontStyle, textTheme.bodyLarge?.fontStyle);
+ expect(labelStyle.fontWeight, textTheme.bodyLarge?.fontWeight);
+ expect(labelStyle.height, textTheme.bodyLarge?.height);
+ expect(labelStyle.inherit, textTheme.bodyLarge?.inherit);
+ expect(labelStyle.leadingDistribution, textTheme.bodyLarge?.leadingDistribution);
+ expect(labelStyle.letterSpacing, textTheme.bodyLarge?.letterSpacing);
+ expect(labelStyle.overflow, textTheme.bodyLarge?.overflow);
+ expect(labelStyle.textBaseline, textTheme.bodyLarge?.textBaseline);
+ expect(labelStyle.wordSpacing, textTheme.bodyLarge?.wordSpacing);
+
+ await tester.pumpWidget(buildFrame(Brightness.dark));
+ await tester.pumpAndSettle(); // Theme transition animation
+ expect(getMaterialBox(tester), paints..rrect(color: const Color(0x1fffffff)));
+ expect(tester.getSize(find.byType(Chip)), const Size(156.0, 48.0));
+ expect(getMaterial(tester).color, null);
+ expect(getMaterial(tester).elevation, 0);
+ expect(getMaterial(tester).shape, const StadiumBorder());
+ expect(getIconData(tester).color?.value, 0xffffffff);
+ expect(getIconData(tester).opacity, null);
+ expect(getIconData(tester).size, null);
+
+ labelStyle = getLabelStyle(tester, 'Chip A').style;
+ expect(labelStyle.color?.value, 0xdeffffff);
+ expect(labelStyle.fontFamily, textTheme.bodyLarge?.fontFamily);
+ expect(labelStyle.fontFamilyFallback, textTheme.bodyLarge?.fontFamilyFallback);
+ expect(labelStyle.fontFeatures, textTheme.bodyLarge?.fontFeatures);
+ expect(labelStyle.fontSize, textTheme.bodyLarge?.fontSize);
+ expect(labelStyle.fontStyle, textTheme.bodyLarge?.fontStyle);
+ expect(labelStyle.fontWeight, textTheme.bodyLarge?.fontWeight);
+ expect(labelStyle.height, textTheme.bodyLarge?.height);
+ expect(labelStyle.inherit, textTheme.bodyLarge?.inherit);
+ expect(labelStyle.leadingDistribution, textTheme.bodyLarge?.leadingDistribution);
+ expect(labelStyle.letterSpacing, textTheme.bodyLarge?.letterSpacing);
+ expect(labelStyle.overflow, textTheme.bodyLarge?.overflow);
+ expect(labelStyle.textBaseline, textTheme.bodyLarge?.textBaseline);
+ expect(labelStyle.wordSpacing, textTheme.bodyLarge?.wordSpacing);
+ });
+
+ testWidgets('Chip uses the right theme colors for the right components', (WidgetTester tester) async {
+ final ThemeData themeData = ThemeData(
+ platform: TargetPlatform.android,
+ primarySwatch: Colors.blue,
+ useMaterial3: false,
+ );
+ final ChipThemeData defaultChipTheme = ChipThemeData.fromDefaults(
+ brightness: themeData.brightness,
+ secondaryColor: Colors.blue,
+ labelStyle: themeData.textTheme.bodyLarge!,
+ );
+ bool value = false;
+ Widget buildApp({
+ ChipThemeData? chipTheme,
+ Widget? avatar,
+ Widget? deleteIcon,
+ bool isSelectable = true,
+ bool isPressable = false,
+ bool isDeletable = true,
+ bool showCheckmark = true,
+ }) {
+ chipTheme ??= defaultChipTheme;
+ return wrapForChip(
+ child: Theme(
+ data: themeData,
+ child: ChipTheme(
+ data: chipTheme,
+ child: StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
+ return RawChip(
+ showCheckmark: showCheckmark,
+ onDeleted: isDeletable ? () { } : null,
+ avatar: avatar,
+ deleteIcon: deleteIcon,
+ isEnabled: isSelectable || isPressable,
+ shape: chipTheme?.shape,
+ selected: isSelectable && value,
+ label: Text('$value'),
+ onSelected: isSelectable
+ ? (bool newValue) {
+ setState(() {
+ value = newValue;
+ });
+ }
+ : null,
+ onPressed: isPressable
+ ? () {
+ setState(() {
+ value = true;
+ });
+ }
+ : null,
+ );
+ }),
+ ),
+ ),
+ );
+ }
+
+ await tester.pumpWidget(buildApp());
+
+ RenderBox materialBox = getMaterialBox(tester);
+ IconThemeData iconData = getIconData(tester);
+ DefaultTextStyle labelStyle = getLabelStyle(tester, 'false');
+
+ // Check default theme for enabled chip.
+ expect(materialBox, paints..rrect(color: defaultChipTheme.backgroundColor));
+ expect(iconData.color, equals(const Color(0xde000000)));
+ expect(labelStyle.style.color, equals(Colors.black.withAlpha(0xde)));
+
+ // Check default theme for disabled chip.
+ await tester.pumpWidget(buildApp(isSelectable: false));
+ await tester.pumpAndSettle();
+ materialBox = getMaterialBox(tester);
+ labelStyle = getLabelStyle(tester, 'false');
+ expect(materialBox, paints..rrect(color: defaultChipTheme.disabledColor));
+ expect(labelStyle.style.color, equals(Colors.black.withAlpha(0xde)));
+
+ // Check default theme for enabled and selected chip.
+ await tester.pumpWidget(buildApp());
+ await tester.pumpAndSettle();
+ await tester.tap(find.byType(RawChip));
+ await tester.pumpAndSettle();
+ materialBox = getMaterialBox(tester);
+ expect(materialBox, paints..rrect(color: defaultChipTheme.selectedColor));
+
+ // Check default theme for disabled and selected chip.
+ await tester.pumpWidget(buildApp(isSelectable: false));
+ await tester.pumpAndSettle();
+ materialBox = getMaterialBox(tester);
+ labelStyle = getLabelStyle(tester, 'true');
+ expect(materialBox, paints..rrect(color: defaultChipTheme.disabledColor));
+ expect(labelStyle.style.color, equals(Colors.black.withAlpha(0xde)));
+
+ // Enable the chip again.
+ await tester.pumpWidget(buildApp());
+ await tester.pumpAndSettle();
+ // Tap to unselect the chip.
+ await tester.tap(find.byType(RawChip));
+ await tester.pumpAndSettle();
+
+ // Apply a custom theme.
+ const Color customColor1 = Color(0xcafefeed);
+ const Color customColor2 = Color(0xdeadbeef);
+ const Color customColor3 = Color(0xbeefcafe);
+ const Color customColor4 = Color(0xaddedabe);
+ final ChipThemeData customTheme = defaultChipTheme.copyWith(
+ brightness: Brightness.dark,
+ backgroundColor: customColor1,
+ disabledColor: customColor2,
+ selectedColor: customColor3,
+ deleteIconColor: customColor4,
+ );
+ await tester.pumpWidget(buildApp(chipTheme: customTheme));
+ await tester.pumpAndSettle();
+ materialBox = getMaterialBox(tester);
+ iconData = getIconData(tester);
+ labelStyle = getLabelStyle(tester, 'false');
+
+ // Check custom theme for enabled chip.
+ expect(materialBox, paints..rrect(color: customTheme.backgroundColor));
+ expect(iconData.color, equals(customTheme.deleteIconColor));
+ expect(labelStyle.style.color, equals(Colors.black.withAlpha(0xde)));
+
+ // Check custom theme with disabled widget.
+ await tester.pumpWidget(buildApp(
+ chipTheme: customTheme,
+ isSelectable: false,
+ ));
+ await tester.pumpAndSettle();
+ materialBox = getMaterialBox(tester);
+ labelStyle = getLabelStyle(tester, 'false');
+ expect(materialBox, paints..rrect(color: customTheme.disabledColor));
+ expect(labelStyle.style.color, equals(Colors.black.withAlpha(0xde)));
+
+ // Check custom theme for enabled and selected chip.
+ await tester.pumpWidget(buildApp(chipTheme: customTheme));
+ await tester.pumpAndSettle();
+ await tester.tap(find.byType(RawChip));
+ await tester.pumpAndSettle();
+ materialBox = getMaterialBox(tester);
+ expect(materialBox, paints..rrect(color: customTheme.selectedColor));
+
+ // Check custom theme for disabled and selected chip.
+ await tester.pumpWidget(buildApp(
+ chipTheme: customTheme,
+ isSelectable: false,
+ ));
+ await tester.pumpAndSettle();
+ materialBox = getMaterialBox(tester);
+ labelStyle = getLabelStyle(tester, 'true');
+ expect(materialBox, paints..rrect(color: customTheme.disabledColor));
+ expect(labelStyle.style.color, equals(Colors.black.withAlpha(0xde)));
+ });
+ });
}
class _MaterialStateOutlinedBorder extends StadiumBorder implements MaterialStateOutlinedBorder {
diff --git a/packages/flutter/test/material/chip_theme_test.dart b/packages/flutter/test/material/chip_theme_test.dart
index ae3b0d9..85e901b 100644
--- a/packages/flutter/test/material/chip_theme_test.dart
+++ b/packages/flutter/test/material/chip_theme_test.dart
@@ -50,6 +50,7 @@
test('ChipThemeData defaults', () {
const ChipThemeData themeData = ChipThemeData();
+ expect(themeData.color, null);
expect(themeData.backgroundColor, null);
expect(themeData.deleteIconColor, null);
expect(themeData.disabledColor, null);
@@ -86,16 +87,17 @@
testWidgets('ChipThemeData implements debugFillProperties', (WidgetTester tester) async {
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
const ChipThemeData(
- backgroundColor: Color(0xfffffff0),
- deleteIconColor: Color(0xfffffff1),
- disabledColor: Color(0xfffffff2),
- selectedColor: Color(0xfffffff3),
- secondarySelectedColor: Color(0xfffffff4),
- shadowColor: Color(0xfffffff5),
- surfaceTintColor: Color(0xfffffff8),
- selectedShadowColor: Color(0xfffffff6),
+ color: MaterialStatePropertyAll<Color>(Color(0xfffffff0)),
+ backgroundColor: Color(0xfffffff1),
+ deleteIconColor: Color(0xfffffff2),
+ disabledColor: Color(0xfffffff3),
+ selectedColor: Color(0xfffffff4),
+ secondarySelectedColor: Color(0xfffffff5),
+ shadowColor: Color(0xfffffff6),
+ surfaceTintColor: Color(0xfffffff7),
+ selectedShadowColor: Color(0xfffffff8),
showCheckmark: true,
- checkmarkColor: Color(0xfffffff7),
+ checkmarkColor: Color(0xfffffff9),
labelPadding: EdgeInsets.all(1),
padding: EdgeInsets.all(2),
side: BorderSide(width: 10),
@@ -113,16 +115,17 @@
.toList();
expect(description, <String>[
- 'backgroundColor: Color(0xfffffff0)',
- 'deleteIconColor: Color(0xfffffff1)',
- 'disabledColor: Color(0xfffffff2)',
- 'selectedColor: Color(0xfffffff3)',
- 'secondarySelectedColor: Color(0xfffffff4)',
- 'shadowColor: Color(0xfffffff5)',
- 'surfaceTintColor: Color(0xfffffff8)',
- 'selectedShadowColor: Color(0xfffffff6)',
+ 'color: MaterialStatePropertyAll(Color(0xfffffff0))',
+ 'backgroundColor: Color(0xfffffff1)',
+ 'deleteIconColor: Color(0xfffffff2)',
+ 'disabledColor: Color(0xfffffff3)',
+ 'selectedColor: Color(0xfffffff4)',
+ 'secondarySelectedColor: Color(0xfffffff5)',
+ 'shadowColor: Color(0xfffffff6)',
+ 'surfaceTintColor: Color(0xfffffff7)',
+ 'selectedShadowColor: Color(0xfffffff8)',
'showCheckmark: true',
- 'checkMarkColor: Color(0xfffffff7)',
+ 'checkMarkColor: Color(0xfffffff9)',
'labelPadding: EdgeInsets.all(1.0)',
'padding: EdgeInsets.all(2.0)',
'side: BorderSide(width: 10.0)',
@@ -330,7 +333,6 @@
expect(chipTheme.pressElevation, 8.0);
});
-
testWidgets('ChipThemeData generates correct opacities for defaults', (WidgetTester tester) async {
const Color customColor1 = Color(0xcafefeed);
const Color customColor2 = Color(0xdeadbeef);
@@ -760,6 +762,111 @@
await tester.pumpWidget(chipWidget(selected: true));
expect(getMaterial(tester).shape, isA<RoundedRectangleBorder>());
});
+
+ testWidgets('RawChip uses material state color from ChipTheme', (WidgetTester tester) async {
+ const Color disabledSelectedColor = Color(0xffffff00);
+ const Color disabledColor = Color(0xff00ff00);
+ const Color backgroundColor = Color(0xff0000ff);
+ const Color selectedColor = Color(0xffff0000);
+ Widget buildApp({ required bool enabled, required bool selected }) {
+ return MaterialApp(
+ theme: ThemeData(
+ chipTheme: ChipThemeData(
+ color: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
+ if (states.contains(MaterialState.disabled)
+ && states.contains(MaterialState.selected)) {
+ return disabledSelectedColor;
+ }
+ if (states.contains(MaterialState.disabled)) {
+ return disabledColor;
+ }
+ if (states.contains(MaterialState.selected)) {
+ return selectedColor;
+ }
+ return backgroundColor;
+ }),
+ ),
+ useMaterial3: true,
+ ),
+ home: Material(
+ child: RawChip(
+ isEnabled: enabled,
+ selected: selected,
+ label: const Text('RawChip'),
+ ),
+ ),
+ );
+ }
+
+ // Check theme color for enabled chip.
+ await tester.pumpWidget(buildApp(enabled: true, selected: false));
+ await tester.pumpAndSettle();
+
+ // Enabled chip should have the provided backgroundColor.
+ expect(getMaterialBox(tester), paints..rrect(color: backgroundColor));
+
+ // Check theme color for disabled chip.
+ await tester.pumpWidget(buildApp(enabled: false, selected: false));
+ await tester.pumpAndSettle();
+
+ // Disabled chip should have the provided disabledColor.
+ expect(getMaterialBox(tester),paints..rrect(color: disabledColor));
+
+ // Check theme color for enabled and selected chip.
+ await tester.pumpWidget(buildApp(enabled: true, selected: true));
+ await tester.pumpAndSettle();
+
+ // Enabled & selected chip should have the provided selectedColor.
+ expect(getMaterialBox(tester), paints..rrect(color: selectedColor));
+
+ // Check theme color for disabled & selected chip.
+ await tester.pumpWidget(buildApp(enabled: false, selected: true));
+ await tester.pumpAndSettle();
+
+ // Disabled & selected chip should have the provided disabledSelectedColor.
+ expect(getMaterialBox(tester), paints..rrect(color: disabledSelectedColor));
+ });
+
+ testWidgets('RawChip uses state colors from ChipTheme', (WidgetTester tester) async {
+ const ChipThemeData chipTheme = ChipThemeData(
+ disabledColor: Color(0xadfefafe),
+ backgroundColor: Color(0xcafefeed),
+ selectedColor: Color(0xbeefcafe),
+ );
+ Widget buildApp({ required bool enabled, required bool selected }) {
+ return MaterialApp(
+ theme: ThemeData(chipTheme: chipTheme, useMaterial3: true),
+ home: Material(
+ child: RawChip(
+ isEnabled: enabled,
+ selected: selected,
+ label: const Text('RawChip'),
+ ),
+ ),
+ );
+ }
+
+ // Check theme color for enabled chip.
+ await tester.pumpWidget(buildApp(enabled: true, selected: false));
+ await tester.pumpAndSettle();
+
+ // Enabled chip should have the provided backgroundColor.
+ expect(getMaterialBox(tester), paints..rrect(color: chipTheme.backgroundColor));
+
+ // Check theme color for disabled chip.
+ await tester.pumpWidget(buildApp(enabled: false, selected: false));
+ await tester.pumpAndSettle();
+
+ // Disabled chip should have the provided disabledColor.
+ expect(getMaterialBox(tester),paints..rrect(color: chipTheme.disabledColor));
+
+ // Check theme color for enabled and selected chip.
+ await tester.pumpWidget(buildApp(enabled: true, selected: true));
+ await tester.pumpAndSettle();
+
+ // Enabled & selected chip should have the provided selectedColor.
+ expect(getMaterialBox(tester), paints..rrect(color: chipTheme.selectedColor));
+ });
}
class _MaterialStateOutlinedBorder extends StadiumBorder implements MaterialStateOutlinedBorder {
diff --git a/packages/flutter/test/material/choice_chip_test.dart b/packages/flutter/test/material/choice_chip_test.dart
index 981d2b2..187ec8f 100644
--- a/packages/flutter/test/material/choice_chip_test.dart
+++ b/packages/flutter/test/material/choice_chip_test.dart
@@ -7,10 +7,10 @@
import '../rendering/mock_canvas.dart';
-RenderBox getMaterialBox(WidgetTester tester) {
+RenderBox getMaterialBox(WidgetTester tester, Finder type) {
return tester.firstRenderObject<RenderBox>(
find.descendant(
- of: find.byType(RawChip),
+ of: type,
matching: find.byType(CustomPaint),
),
);
@@ -19,7 +19,7 @@
Material getMaterial(WidgetTester tester) {
return tester.widget<Material>(
find.descendant(
- of: find.byType(RawChip),
+ of: find.byType(ChoiceChip),
matching: find.byType(Material),
),
);
@@ -40,9 +40,10 @@
TextDirection textDirection = TextDirection.ltr,
double textScaleFactor = 1.0,
Brightness brightness = Brightness.light,
+ bool? useMaterial3,
}) {
return MaterialApp(
- theme: ThemeData(brightness: brightness),
+ theme: ThemeData(brightness: brightness, useMaterial3: useMaterial3),
home: Directionality(
textDirection: textDirection,
child: MediaQuery(
@@ -327,6 +328,180 @@
expect(decoration.color, theme.colorScheme.onSurface.withOpacity(0.12));
});
+ testWidgets('ChoiceChip.color resolves material states', (WidgetTester tester) async {
+ const Color disabledSelectedColor = Color(0xffffff00);
+ const Color disabledColor = Color(0xff00ff00);
+ const Color backgroundColor = Color(0xff0000ff);
+ const Color selectedColor = Color(0xffff0000);
+ final MaterialStateProperty<Color?> color = MaterialStateProperty.resolveWith((Set<MaterialState> states) {
+ if (states.contains(MaterialState.disabled) && states.contains(MaterialState.selected)) {
+ return disabledSelectedColor;
+ }
+ if (states.contains(MaterialState.disabled)) {
+ return disabledColor;
+ }
+ if (states.contains(MaterialState.selected)) {
+ return selectedColor;
+ }
+ return backgroundColor;
+ });
+ Widget buildApp({ required bool enabled, required bool selected }) {
+ return wrapForChip(
+ useMaterial3: true,
+ child: Column(
+ children: <Widget>[
+ ChoiceChip(
+ onSelected: enabled ? (bool value) { } : null,
+ selected: selected,
+ color: color,
+ label: const Text('ChoiceChip'),
+ ),
+ ChoiceChip.elevated(
+ onSelected: enabled ? (bool value) { } : null,
+ selected: selected,
+ color: color,
+ label: const Text('ChoiceChip.elevated'),
+ ),
+ ],
+ ),
+ );
+ }
+
+ // Test enabled state.
+ await tester.pumpWidget(buildApp(enabled: true, selected: false));
+
+ // Enabled ChoiceChip should have the provided backgroundColor.
+ expect(
+ getMaterialBox(tester, find.byType(RawChip).first),
+ paints..rrect(color: backgroundColor),
+ );
+ // Enabled elevated ChoiceChip should have the provided backgroundColor.
+ expect(
+ getMaterialBox(tester, find.byType(RawChip).last),
+ paints..rrect(color: backgroundColor),
+ );
+
+ // Test disabled state.
+ await tester.pumpWidget(buildApp(enabled: false, selected: false));
+ await tester.pumpAndSettle();
+
+ // Disabled ChoiceChip should have the provided disabledColor.
+ expect(
+ getMaterialBox(tester, find.byType(RawChip).first),
+ paints..rrect(color: disabledColor),
+ );
+ // Disabled elevated ChoiceChip should have the provided disabledColor.
+ expect(
+ getMaterialBox(tester, find.byType(RawChip).last),
+ paints..rrect(color: disabledColor),
+ );
+
+ // Test enabled & selected state.
+ await tester.pumpWidget(buildApp(enabled: true, selected: true));
+ await tester.pumpAndSettle();
+
+ // Enabled & selected ChoiceChip should have the provided selectedColor.
+ expect(
+ getMaterialBox(tester, find.byType(RawChip).first),
+ paints..rrect(color: selectedColor),
+ );
+ // Enabled & selected elevated ChoiceChip should have the provided selectedColor.
+ expect(
+ getMaterialBox(tester, find.byType(RawChip).last),
+ paints..rrect(color: selectedColor),
+ );
+
+ // Test disabled & selected state.
+ await tester.pumpWidget(buildApp(enabled: false, selected: true));
+ await tester.pumpAndSettle();
+
+ // Disabled & selected ChoiceChip should have the provided disabledSelectedColor.
+ expect(
+ getMaterialBox(tester, find.byType(RawChip).first),
+ paints..rrect(color: disabledSelectedColor),
+ );
+ // Disabled & selected elevated ChoiceChip should have the provided disabledSelectedColor.
+ expect(
+ getMaterialBox(tester, find.byType(RawChip).last),
+ paints..rrect(color: disabledSelectedColor),
+ );
+ });
+
+ testWidgets('ChoiceChip uses provided state color properties', (WidgetTester tester) async {
+ const Color disabledColor = Color(0xff00ff00);
+ const Color backgroundColor = Color(0xff0000ff);
+ const Color selectedColor = Color(0xffff0000);
+ Widget buildApp({ required bool enabled, required bool selected }) {
+ return wrapForChip(
+ useMaterial3: true,
+ child: Column(
+ children: <Widget>[
+ ChoiceChip(
+ onSelected: enabled ? (bool value) { } : null,
+ selected: selected,
+ disabledColor: disabledColor,
+ backgroundColor: backgroundColor,
+ selectedColor: selectedColor,
+ label: const Text('ChoiceChip'),
+ ),
+ ChoiceChip.elevated(
+ onSelected: enabled ? (bool value) { } : null,
+ selected: selected,
+ disabledColor: disabledColor,
+ backgroundColor: backgroundColor,
+ selectedColor: selectedColor,
+ label: const Text('ChoiceChip.elevated'),
+ ),
+ ],
+ ),
+ );
+ }
+
+ // Test enabled chips.
+ await tester.pumpWidget(buildApp(enabled: true, selected: false));
+
+ // Enabled ChoiceChip should have the provided backgroundColor.
+ expect(
+ getMaterialBox(tester, find.byType(RawChip).first),
+ paints..rrect(color: backgroundColor),
+ );
+ // Enabled elevated ChoiceChip should have the provided backgroundColor.
+ expect(
+ getMaterialBox(tester, find.byType(RawChip).last),
+ paints..rrect(color: backgroundColor),
+ );
+
+ // Test disabled chips.
+ await tester.pumpWidget(buildApp(enabled: false, selected: false));
+ await tester.pumpAndSettle();
+
+ // Disabled ChoiceChip should have the provided disabledColor.
+ expect(
+ getMaterialBox(tester, find.byType(RawChip).first),
+ paints..rrect(color: disabledColor),
+ );
+ // Disabled elevated ChoiceChip should have the provided disabledColor.
+ expect(
+ getMaterialBox(tester, find.byType(RawChip).last),
+ paints..rrect(color: disabledColor),
+ );
+
+ // Test enabled & selected chips.
+ await tester.pumpWidget(buildApp(enabled: true, selected: true));
+ await tester.pumpAndSettle();
+
+ // Enabled & selected ChoiceChip should have the provided selectedColor.
+ expect(
+ getMaterialBox(tester, find.byType(RawChip).first),
+ paints..rrect(color: selectedColor),
+ );
+ // Enabled & selected elevated ChoiceChip should have the provided selectedColor.
+ expect(
+ getMaterialBox(tester, find.byType(RawChip).last),
+ paints..rrect(color: selectedColor),
+ );
+ });
+
testWidgets('ChoiceChip can be tapped', (WidgetTester tester) async {
await tester.pumpWidget(
const MaterialApp(
@@ -416,7 +591,7 @@
}
await tester.pumpWidget(buildFrame(Brightness.light));
- expect(getMaterialBox(tester), paints..rrect(color: const Color(0x3d000000)));
+ expect(getMaterialBox(tester, find.byType(RawChip)), paints..rrect(color: const Color(0x3d000000)));
expect(tester.getSize(find.byType(ChoiceChip)), const Size(108.0, 48.0));
expect(getMaterial(tester).color, null);
expect(getMaterial(tester).elevation, 0);
@@ -425,7 +600,7 @@
await tester.pumpWidget(buildFrame(Brightness.dark));
await tester.pumpAndSettle(); // Theme transition animation
- expect(getMaterialBox(tester), paints..rrect(color: const Color(0x3dffffff)));
+ expect(getMaterialBox(tester, find.byType(RawChip)), paints..rrect(color: const Color(0x3dffffff)));
expect(tester.getSize(find.byType(ChoiceChip)), const Size(108.0, 48.0));
expect(getMaterial(tester).color, null);
expect(getMaterial(tester).elevation, 0);
diff --git a/packages/flutter/test/material/date_picker_test.dart b/packages/flutter/test/material/date_picker_test.dart
index a7281b8..514a5f4 100644
--- a/packages/flutter/test/material/date_picker_test.dart
+++ b/packages/flutter/test/material/date_picker_test.dart
@@ -1268,6 +1268,7 @@
expect(tester.getSemantics(find.text('3')), matchesSemantics(
label: '3, Sunday, January 3, 2016, Today',
+ isButton: true,
hasTapAction: true,
isFocusable: true,
));
diff --git a/packages/flutter/test/material/date_picker_theme_test.dart b/packages/flutter/test/material/date_picker_theme_test.dart
index 18da052..191c6fa 100644
--- a/packages/flutter/test/material/date_picker_theme_test.dart
+++ b/packages/flutter/test/material/date_picker_theme_test.dart
@@ -40,7 +40,11 @@
rangePickerHeaderHelpStyle: TextStyle(fontSize: 15),
rangeSelectionBackgroundColor: Color(0xffffff2f),
rangeSelectionOverlayColor: MaterialStatePropertyAll<Color>(Color(0xffffff3f)),
- dividerColor: Color(0xffffff3f),
+ dividerColor: Color(0xffffff4f),
+ inputDecorationTheme: InputDecorationTheme(
+ fillColor: Color(0xffffff5f),
+ border: UnderlineInputBorder(),
+ )
);
Material findDialogMaterial(WidgetTester tester) {
@@ -119,6 +123,7 @@
expect(theme.rangeSelectionBackgroundColor, null);
expect(theme.rangeSelectionOverlayColor, null);
expect(theme.dividerColor, null);
+ expect(theme.inputDecorationTheme, null);
});
testWidgets('DatePickerTheme.defaults M3 defaults', (WidgetTester tester) async {
@@ -129,7 +134,7 @@
await tester.pumpWidget(
MaterialApp(
- theme: ThemeData.light(useMaterial3: true),
+ theme: ThemeData(useMaterial3: true),
home: Builder(
builder: (BuildContext context) {
m3 = DatePickerTheme.defaults(context);
@@ -193,6 +198,7 @@
expect(m3.rangePickerHeaderHeadlineStyle, textTheme.titleLarge);
expect(m3.rangePickerHeaderHelpStyle, textTheme.titleSmall);
expect(m3.dividerColor, null);
+ expect(m3.inputDecorationTheme, null);
});
testWidgets('DatePickerTheme.defaults M2 defaults', (WidgetTester tester) async {
@@ -203,7 +209,7 @@
await tester.pumpWidget(
MaterialApp(
- theme: ThemeData.light(useMaterial3: false),
+ theme: ThemeData(useMaterial3: false),
home: Builder(
builder: (BuildContext context) {
m2 = DatePickerTheme.defaults(context);
@@ -258,6 +264,8 @@
expect(m2.rangePickerHeaderForegroundColor, colorScheme.onPrimary);
expect(m2.rangePickerHeaderHeadlineStyle, textTheme.headlineSmall);
expect(m2.rangePickerHeaderHelpStyle, textTheme.labelSmall);
+ expect(m2.dividerColor, null);
+ expect(m2.inputDecorationTheme, null);
});
testWidgets('Default DatePickerThemeData debugFillProperties', (WidgetTester tester) async {
@@ -282,7 +290,9 @@
.map((DiagnosticsNode node) => node.toString())
.toList();
- expect(description, <String>[
+ expect(
+ description,
+ equalsIgnoringHashCodes(<String>[
'backgroundColor: Color(0xfffffff0)',
'elevation: 6.0',
'shadowColor: Color(0xfffffff1)',
@@ -315,15 +325,18 @@
'rangePickerHeaderHelpStyle: TextStyle(inherit: true, size: 15.0)',
'rangeSelectionBackgroundColor: Color(0xffffff2f)',
'rangeSelectionOverlayColor: MaterialStatePropertyAll(Color(0xffffff3f))',
- 'dividerColor: Color(0xffffff3f)',
- ]);
+ 'dividerColor: Color(0xffffff4f)',
+ 'inputDecorationTheme: InputDecorationTheme#00000(fillColor: Color(0xffffff5f), border: UnderlineInputBorder())'
+ ]),
+ );
});
- testWidgets('DatePickerDialog uses ThemeData datePicker theme', (WidgetTester tester) async {
+ testWidgets('DatePickerDialog uses ThemeData datePicker theme (calendar mode)', (WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
- theme: ThemeData.light(useMaterial3: true).copyWith(
+ theme: ThemeData(
datePickerTheme: datePickerTheme,
+ useMaterial3: true,
),
home: Directionality(
textDirection: TextDirection.ltr,
@@ -398,11 +411,53 @@
expect(year2023Decoration.border?.bottom.color, datePickerTheme.todayForegroundColor?.resolve(<MaterialState>{}));
});
+ testWidgets('DatePickerDialog uses ThemeData datePicker theme (input mode)', (WidgetTester tester) async {
+ await tester.pumpWidget(
+ MaterialApp(
+ theme: ThemeData(
+ datePickerTheme: datePickerTheme,
+ useMaterial3: true,
+ ),
+ home: Directionality(
+ textDirection: TextDirection.ltr,
+ child: Material(
+ child: Center(
+ child: DatePickerDialog(
+ initialEntryMode: DatePickerEntryMode.input,
+ initialDate: DateTime(2023, DateTime.january, 25),
+ firstDate: DateTime(2022),
+ lastDate: DateTime(2024, DateTime.december, 31),
+ currentDate: DateTime(2023, DateTime.january, 24),
+ ),
+ ),
+ ),
+ ),
+ ),
+ );
+
+ final Material material = findDialogMaterial(tester);
+ expect(material.color, datePickerTheme.backgroundColor);
+ expect(material.elevation, datePickerTheme.elevation);
+ expect(material.shadowColor, datePickerTheme.shadowColor);
+ expect(material.surfaceTintColor, datePickerTheme.surfaceTintColor);
+ expect(material.shape, datePickerTheme.shape);
+
+ final Text selectDate = tester.widget<Text>(find.text('Select date'));
+ final Material headerMaterial = findHeaderMaterial(tester, 'Select date');
+ expect(selectDate.style?.color, datePickerTheme.headerForegroundColor);
+ expect(selectDate.style?.fontSize, datePickerTheme.headerHelpStyle?.fontSize);
+ expect(headerMaterial.color, datePickerTheme.headerBackgroundColor);
+
+ final InputDecoration inputDecoration = tester.widget<TextField>(find.byType(TextField)).decoration!;
+ expect(inputDecoration.fillColor, datePickerTheme.inputDecorationTheme?.fillColor);
+ });
+
testWidgets('DateRangePickerDialog uses ThemeData datePicker theme', (WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
- theme: ThemeData.light(useMaterial3: true).copyWith(
+ theme: ThemeData(
datePickerTheme: datePickerTheme,
+ useMaterial3: true,
),
home: Directionality(
textDirection: TextDirection.ltr,
@@ -450,8 +505,9 @@
addTearDown(tester.view.reset);
await tester.pumpWidget(
MaterialApp(
- theme: ThemeData.light(useMaterial3: true).copyWith(
+ theme: ThemeData(
datePickerTheme: datePickerTheme,
+ useMaterial3: true,
),
home: Directionality(
textDirection: TextDirection.ltr,
@@ -482,4 +538,60 @@
final Divider horizontalDivider = tester.widget(find.byType(Divider));
expect(horizontalDivider.color, datePickerTheme.dividerColor);
});
+
+ testWidgets(
+ 'DatePicker uses ThemeData.inputDecorationTheme properties '
+ 'which are null in DatePickerThemeData.inputDecorationTheme',
+ (WidgetTester tester) async {
+
+ Widget buildWidget({
+ InputDecorationTheme? inputDecorationTheme,
+ DatePickerThemeData? datePickerTheme,
+ }) {
+ return MaterialApp(
+ theme: ThemeData(
+ useMaterial3: true,
+ inputDecorationTheme: inputDecorationTheme,
+ datePickerTheme: datePickerTheme,
+ ),
+ home: Directionality(
+ textDirection: TextDirection.ltr,
+ child: Material(
+ child: Center(
+ child: DatePickerDialog(
+ initialEntryMode: DatePickerEntryMode.input,
+ initialDate: DateTime(2023, DateTime.january, 25),
+ firstDate: DateTime(2022),
+ lastDate: DateTime(2024, DateTime.december, 31),
+ currentDate: DateTime(2023, DateTime.january, 24),
+ ),
+ ),
+ ),
+ ),
+ );
+ }
+
+ // Test DatePicker with DatePickerThemeData.inputDecorationTheme.
+ await tester.pumpWidget(buildWidget(
+ inputDecorationTheme: const InputDecorationTheme(filled: true),
+ datePickerTheme: datePickerTheme,
+ ));
+ InputDecoration inputDecoration = tester.widget<TextField>(find.byType(TextField)).decoration!;
+ expect(inputDecoration.fillColor, datePickerTheme.inputDecorationTheme!.fillColor);
+ expect(inputDecoration.border , datePickerTheme.inputDecorationTheme!.border);
+
+ // Test DatePicker with ThemeData.inputDecorationTheme.
+ await tester.pumpWidget(buildWidget(
+ inputDecorationTheme: const InputDecorationTheme(
+ filled: true,
+ fillColor: Color(0xFF00FF00),
+ border: OutlineInputBorder(),
+ ),
+ ));
+ await tester.pumpAndSettle();
+
+ inputDecoration = tester.widget<TextField>(find.byType(TextField)).decoration!;
+ expect(inputDecoration.fillColor, const Color(0xFF00FF00));
+ expect(inputDecoration.border , const OutlineInputBorder());
+ });
}
diff --git a/packages/flutter/test/material/divider_test.dart b/packages/flutter/test/material/divider_test.dart
index 7136767..127af32 100644
--- a/packages/flutter/test/material/divider_test.dart
+++ b/packages/flutter/test/material/divider_test.dart
@@ -4,16 +4,29 @@
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
+
import '../rendering/mock_canvas.dart';
void main() {
- testWidgets('Divider control test', (WidgetTester tester) async {
+ testWidgets('Material3 - Divider control test', (WidgetTester tester) async {
+ await tester.pumpWidget(
+ MaterialApp(
+ theme: ThemeData(useMaterial3: true),
+ home: const Center(child: Divider()),
+ ),
+ );
+ final RenderBox box = tester.firstRenderObject(find.byType(Divider));
+ expect(box.size.height, 16.0);
+ final Container container = tester.widget(find.byType(Container));
+ final BoxDecoration decoration = container.decoration! as BoxDecoration;
+ expect(decoration.border!.bottom.width, 1.0);
+ });
+
+ testWidgets('Material2 - Divider control test', (WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(useMaterial3: false),
- home: const Center(
- child: Divider(),
- ),
+ home: const Center(child: Divider()),
),
);
final RenderBox box = tester.firstRenderObject(find.byType(Divider));
@@ -27,11 +40,7 @@
await tester.pumpWidget(
const Directionality(
textDirection: TextDirection.ltr,
- child: Center(
- child: Divider(
- thickness: 5.0,
- ),
- ),
+ child: Center(child: Divider(thickness: 5.0)),
),
);
final Container container = tester.widget(find.byType(Container));
@@ -47,11 +56,7 @@
await tester.pumpWidget(
const Directionality(
textDirection: TextDirection.ltr,
- child: Center(
- child: Divider(
- indent: customIndent,
- ),
- ),
+ child: Center(child: Divider(indent: customIndent)),
),
);
// The divider line is drawn with a DecoratedBox with a border
@@ -63,11 +68,7 @@
await tester.pumpWidget(
const Directionality(
textDirection: TextDirection.ltr,
- child: Center(
- child: Divider(
- endIndent: customIndent,
- ),
- ),
+ child: Center(child: Divider(endIndent: customIndent)),
),
);
dividerRect = tester.getRect(find.byType(Divider));
@@ -92,13 +93,26 @@
expect(lineRect.right, dividerRect.right - customIndent);
});
- testWidgets('Vertical Divider Test', (WidgetTester tester) async {
+ testWidgets('Material3 - Vertical Divider Test', (WidgetTester tester) async {
+ await tester.pumpWidget(
+ MaterialApp(
+ theme: ThemeData(useMaterial3: true),
+ home: const Center(child: VerticalDivider()),
+ ),
+ );
+ final RenderBox box = tester.firstRenderObject(find.byType(VerticalDivider));
+ expect(box.size.width, 16.0);
+ final Container container = tester.widget(find.byType(Container));
+ final BoxDecoration decoration = container.decoration! as BoxDecoration;
+ final Border border = decoration.border! as Border;
+ expect(border.left.width, 1.0);
+ });
+
+ testWidgets('Material2 - Vertical Divider Test', (WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(useMaterial3: false),
- home: const Center(
- child: VerticalDivider(),
- ),
+ home: const Center(child: VerticalDivider()),
),
);
final RenderBox box = tester.firstRenderObject(find.byType(VerticalDivider));
@@ -113,11 +127,7 @@
await tester.pumpWidget(
const Directionality(
textDirection: TextDirection.ltr,
- child: Center(
- child: VerticalDivider(
- thickness: 5.0,
- ),
- ),
+ child: Center(child: VerticalDivider(thickness: 5.0)),
),
);
final Container container = tester.widget(find.byType(Container));
@@ -158,11 +168,7 @@
await tester.pumpWidget(
const Directionality(
textDirection: TextDirection.ltr,
- child: Center(
- child: VerticalDivider(
- indent: customIndent,
- ),
- ),
+ child: Center(child: VerticalDivider(indent: customIndent)),
),
);
// The divider line is drawn with a DecoratedBox with a border
@@ -174,11 +180,7 @@
await tester.pumpWidget(
const Directionality(
textDirection: TextDirection.ltr,
- child: Center(
- child: VerticalDivider(
- endIndent: customIndent,
- ),
- ),
+ child: Center(child: VerticalDivider(endIndent: customIndent)),
),
);
dividerRect = tester.getRect(find.byType(VerticalDivider));
diff --git a/packages/flutter/test/material/divider_theme_test.dart b/packages/flutter/test/material/divider_theme_test.dart
index 49afe07..6928a79 100644
--- a/packages/flutter/test/material/divider_theme_test.dart
+++ b/packages/flutter/test/material/divider_theme_test.dart
@@ -26,9 +26,9 @@
const DividerThemeData().debugFillProperties(builder);
final List<String> description = builder.properties
- .where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
- .map((DiagnosticsNode node) => node.toString())
- .toList();
+ .where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
+ .map((DiagnosticsNode node) => node.toString())
+ .toList();
expect(description, <String>[]);
});
@@ -44,9 +44,9 @@
).debugFillProperties(builder);
final List<String> description = builder.properties
- .where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
- .map((DiagnosticsNode node) => node.toString())
- .toList();
+ .where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
+ .map((DiagnosticsNode node) => node.toString())
+ .toList();
expect(description, <String>[
'color: Color(0xffffffff)',
@@ -57,7 +57,7 @@
]);
});
- group('Horizontal Divider', () {
+ group('Material3 - Horizontal Divider', () {
testWidgets('Passing no DividerThemeData returns defaults', (WidgetTester tester) async {
final ThemeData theme = ThemeData(useMaterial3: true);
await tester.pumpWidget(MaterialApp(
@@ -159,7 +159,7 @@
});
});
- group('Vertical Divider', () {
+ group('Material3 - Vertical Divider', () {
testWidgets('Passing no DividerThemeData returns defaults', (WidgetTester tester) async {
final ThemeData theme = ThemeData(useMaterial3: true);
await tester.pumpWidget(MaterialApp(
@@ -270,7 +270,7 @@
// support is deprecated and the APIs are removed, these tests
// can be deleted.
- group('Horizontal Divider', () {
+ group('Material2 - Horizontal Divider', () {
testWidgets('Passing no DividerThemeData returns defaults', (WidgetTester tester) async {
await tester.pumpWidget(MaterialApp(
theme: ThemeData(useMaterial3: false),
@@ -313,7 +313,7 @@
});
});
- group('Vertical Divider', () {
+ group('Material2 - Vertical Divider', () {
testWidgets('Passing no DividerThemeData returns defaults', (WidgetTester tester) async {
await tester.pumpWidget(MaterialApp(
theme: ThemeData(useMaterial3: false),
diff --git a/packages/flutter/test/material/dropdown_menu_test.dart b/packages/flutter/test/material/dropdown_menu_test.dart
index 6ec5e48..6642efd 100644
--- a/packages/flutter/test/material/dropdown_menu_test.dart
+++ b/packages/flutter/test/material/dropdown_menu_test.dart
@@ -112,7 +112,7 @@
testWidgets('The width of the text field should always be the same as the menu view',
(WidgetTester tester) async {
- final ThemeData themeData = ThemeData();
+ final ThemeData themeData = ThemeData(useMaterial3: false);
final bool useMaterial3 = themeData.useMaterial3;
await tester.pumpWidget(
MaterialApp(
@@ -216,6 +216,70 @@
expect(box.size.width, customWidth);
});
+ testWidgets('The width of MenuAnchor respects MenuAnchor.expandedInsets', (WidgetTester tester) async {
+ const double parentWidth = 500.0;
+ final List<DropdownMenuEntry<ShortMenu>> shortMenuItems = <DropdownMenuEntry<ShortMenu>>[];
+ for (final ShortMenu value in ShortMenu.values) {
+ final DropdownMenuEntry<ShortMenu> entry = DropdownMenuEntry<ShortMenu>(value: value, label: value.label);
+ shortMenuItems.add(entry);
+ }
+ Widget buildMenuAnchor({EdgeInsets? expandedInsets}) {
+ return MaterialApp(
+ home: Scaffold(
+ body: SizedBox(
+ width: parentWidth,
+ height: parentWidth,
+ child: DropdownMenu<ShortMenu>(
+ expandedInsets: expandedInsets,
+ dropdownMenuEntries: shortMenuItems,
+ ),
+ ),
+ ),
+ );
+ }
+
+ // By default, the width of the text field is determined by the menu children.
+ await tester.pumpWidget(buildMenuAnchor());
+ RenderBox box = tester.firstRenderObject(find.byType(TextField));
+ expect(box.size.width, 136.0);
+
+ await tester.tap(find.byType(TextField));
+ await tester.pumpAndSettle();
+
+ Size buttonSize = tester.getSize(find.widgetWithText(MenuItemButton, 'I0').hitTestable());
+ expect(buttonSize.width, 136.0);
+
+ // If expandedInsets is EdgeInsets.zero, the width should be the same as its parent.
+ await tester.pumpWidget(Container());
+ await tester.pumpWidget(buildMenuAnchor(expandedInsets: EdgeInsets.zero));
+ box = tester.firstRenderObject(find.byType(TextField));
+ expect(box.size.width, parentWidth);
+
+ await tester.tap(find.byType(TextField));
+ await tester.pumpAndSettle();
+
+ buttonSize = tester.getSize(find.widgetWithText(MenuItemButton, 'I0'));
+ expect(buttonSize.width, parentWidth);
+
+ // If expandedInsets is not zero, the width of the text field should be adjusted
+ // based on the EdgeInsets.left and EdgeInsets.right. The top and bottom values
+ // will be ignored.
+ await tester.pumpWidget(Container());
+ await tester.pumpWidget(buildMenuAnchor(expandedInsets: const EdgeInsets.only(left: 35.0, top: 50.0, right: 20.0)));
+ box = tester.firstRenderObject(find.byType(TextField));
+ expect(box.size.width, parentWidth - 35.0 - 20.0);
+ final Rect containerRect = tester.getRect(find.byType(SizedBox).first);
+ final Rect dropdownMenuRect = tester.getRect(find.byType(TextField));
+ expect(dropdownMenuRect.top, containerRect.top);
+
+
+ await tester.tap(find.byType(TextField));
+ await tester.pumpAndSettle();
+
+ buttonSize = tester.getSize(find.widgetWithText(MenuItemButton, 'I0'));
+ expect(buttonSize.width, parentWidth - 35.0 - 20.0);
+ });
+
testWidgets('The menuHeight property can be used to show a shorter scrollable menu list instead of the complete list',
(WidgetTester tester) async {
final ThemeData themeData = ThemeData();
@@ -1315,6 +1379,29 @@
await tester.pumpWidget(buildFrame());
expect(find.text(errorText), findsOneWidget);
});
+
+ testWidgets('Can scroll to the highlighted item', (WidgetTester tester) async {
+ await tester.pumpWidget(MaterialApp(
+ home: Scaffold(
+ body: DropdownMenu<TestMenu>(
+ requestFocusOnTap: true,
+ menuHeight: 100, // Give a small number so the list can only show 2 or 3 items.
+ dropdownMenuEntries: menuChildren,
+ ),
+ ),
+ ));
+ await tester.pumpAndSettle();
+
+ await tester.tap(find.byType(DropdownMenu<TestMenu>));
+ await tester.pumpAndSettle();
+
+ expect(find.text('Item 5').hitTestable(), findsNothing);
+ await tester.enterText(find.byType(TextField), '5');
+ await tester.pumpAndSettle();
+ // Item 5 should show up.
+ expect(find.text('Item 5').hitTestable(), findsOneWidget);
+ });
+
}
enum TestMenu {
diff --git a/packages/flutter/test/material/expansion_tile_theme_test.dart b/packages/flutter/test/material/expansion_tile_theme_test.dart
index 323d3eb..cb29a39 100644
--- a/packages/flutter/test/material/expansion_tile_theme_test.dart
+++ b/packages/flutter/test/material/expansion_tile_theme_test.dart
@@ -290,7 +290,7 @@
// Check the expanded text color when textColor is applied.
expect(getTextColor(), textColor);
// Check the expanded ShapeBorder when shape is applied.
- expect(shapeDecoration.shape, collapsedShape);
+ expect(shapeDecoration.shape, shape);
// Check the child position when expandedAlignment is applied.
final Rect childRect = tester.getRect(find.text('Tile 1'));
diff --git a/packages/flutter/test/material/filter_chip_test.dart b/packages/flutter/test/material/filter_chip_test.dart
index 94c19e1..c4aaa40 100644
--- a/packages/flutter/test/material/filter_chip_test.dart
+++ b/packages/flutter/test/material/filter_chip_test.dart
@@ -78,6 +78,15 @@
);
}
+RenderBox getMaterialBox(WidgetTester tester, Finder type) {
+ return tester.firstRenderObject<RenderBox>(
+ find.descendant(
+ of: type,
+ matching: find.byType(CustomPaint),
+ ),
+ );
+}
+
void checkChipMaterialClipBehavior(WidgetTester tester, Clip clipBehavior) {
final Iterable<Material> materials = tester.widgetList<Material>(find.byType(Material));
// There should be two Material widgets, first Material is from the "_wrapForChip" and
@@ -370,6 +379,181 @@
expect(decoration.color, theme.colorScheme.onSurface.withOpacity(0.12));
});
+ testWidgets('FilterChip.color resolves material states', (WidgetTester tester) async {
+ const Color disabledSelectedColor = Color(0xffffff00);
+ const Color disabledColor = Color(0xff00ff00);
+ const Color backgroundColor = Color(0xff0000ff);
+ const Color selectedColor = Color(0xffff0000);
+ final MaterialStateProperty<Color?> color = MaterialStateProperty.resolveWith((Set<MaterialState> states) {
+ if (states.contains(MaterialState.disabled) && states.contains(MaterialState.selected)) {
+ return disabledSelectedColor;
+ }
+ if (states.contains(MaterialState.disabled)) {
+ return disabledColor;
+ }
+ if (states.contains(MaterialState.selected)) {
+ return selectedColor;
+ }
+ return backgroundColor;
+ });
+ Widget buildApp({ required bool enabled, required bool selected }) {
+ return wrapForChip(
+ useMaterial3: true,
+ child: Column(
+ children: <Widget>[
+ FilterChip(
+ onSelected: enabled ? (bool value) { } : null,
+ selected: selected,
+ color: color,
+ label: const Text('FilterChip'),
+ ),
+ FilterChip.elevated(
+ onSelected: enabled ? (bool value) { } : null,
+ selected: selected,
+ color: color,
+ label: const Text('FilterChip.elevated'),
+ ),
+ ],
+ ),
+ );
+ }
+
+ // Test enabled state.
+ await tester.pumpWidget(buildApp(enabled: true, selected: false));
+
+ // Enabled FilterChip should have the provided backgroundColor.
+ expect(
+ getMaterialBox(tester, find.byType(RawChip).first),
+ paints..rrect(color: backgroundColor),
+ );
+ // Enabled elevated FilterChip should have the provided backgroundColor.
+ expect(
+ getMaterialBox(tester, find.byType(RawChip).last),
+ paints..rrect(color: backgroundColor),
+ );
+
+ // Test disabled state.
+ await tester.pumpWidget(buildApp(enabled: false, selected: false));
+ await tester.pumpAndSettle();
+
+ // Disabled FilterChip should have the provided disabledColor.
+ expect(
+ getMaterialBox(tester, find.byType(RawChip).first),
+ paints..rrect(color: disabledColor),
+ );
+ // Disabled elevated FilterChip should have the provided disabledColor.
+ expect(
+ getMaterialBox(tester, find.byType(RawChip).last),
+ paints..rrect(color: disabledColor),
+ );
+
+ // Test enabled & selected state.
+ await tester.pumpWidget(buildApp(enabled: true, selected: true));
+ await tester.pumpAndSettle();
+
+ // Enabled & selected FilterChip should have the provided selectedColor.
+ expect(
+ getMaterialBox(tester, find.byType(RawChip).first),
+ paints..rrect(color: selectedColor),
+ );
+ // Enabled & selected elevated FilterChip should have the provided selectedColor.
+ expect(
+ getMaterialBox(tester, find.byType(RawChip).last),
+ paints..rrect(color: selectedColor),
+ );
+
+ // Test disabled & selected state.
+ await tester.pumpWidget(buildApp(enabled: false, selected: true));
+ await tester.pumpAndSettle();
+
+ // Disabled & selected FilterChip should have the provided disabledSelectedColor.
+ expect(
+ getMaterialBox(tester, find.byType(RawChip).first),
+ paints..rrect(color: disabledSelectedColor),
+ );
+ // Disabled & selected elevated FilterChip should have the
+ // provided disabledSelectedColor.
+ expect(
+ getMaterialBox(tester, find.byType(RawChip).last),
+ paints..rrect(color: disabledSelectedColor),
+ );
+ });
+
+ testWidgets('FilterChip uses provided state color properties', (WidgetTester tester) async {
+ const Color disabledColor = Color(0xff00ff00);
+ const Color backgroundColor = Color(0xff0000ff);
+ const Color selectedColor = Color(0xffff0000);
+ Widget buildApp({ required bool enabled, required bool selected }) {
+ return wrapForChip(
+ useMaterial3: true,
+ child: Column(
+ children: <Widget>[
+ FilterChip(
+ onSelected: enabled ? (bool value) { } : null,
+ selected: selected,
+ disabledColor: disabledColor,
+ backgroundColor: backgroundColor,
+ selectedColor: selectedColor,
+ label: const Text('FilterChip'),
+ ),
+ FilterChip.elevated(
+ onSelected: enabled ? (bool value) { } : null,
+ selected: selected,
+ disabledColor: disabledColor,
+ backgroundColor: backgroundColor,
+ selectedColor: selectedColor,
+ label: const Text('FilterChip.elevated'),
+ ),
+ ],
+ ),
+ );
+ }
+
+ // Test enabled state.
+ await tester.pumpWidget(buildApp(enabled: true, selected: false));
+
+ // Enabled FilterChip should have the provided backgroundColor.
+ expect(
+ getMaterialBox(tester, find.byType(RawChip).first),
+ paints..rrect(color: backgroundColor),
+ );
+ // Enabled elevated FilterChip should have the provided backgroundColor.
+ expect(
+ getMaterialBox(tester, find.byType(RawChip).last),
+ paints..rrect(color: backgroundColor),
+ );
+
+ // Test disabled state.
+ await tester.pumpWidget(buildApp(enabled: false, selected: false));
+ await tester.pumpAndSettle();
+
+ // Disabled FilterChip should have the provided disabledColor.
+ expect(
+ getMaterialBox(tester, find.byType(RawChip).first),
+ paints..rrect(color: disabledColor),
+ );
+ // Disabled elevated FilterChip should have the provided disabledColor.
+ expect(
+ getMaterialBox(tester, find.byType(RawChip).last),
+ paints..rrect(color: disabledColor),
+ );
+
+ // Test enabled & selected state.
+ await tester.pumpWidget(buildApp(enabled: true, selected: true));
+ await tester.pumpAndSettle();
+
+ // Enabled & selected FilterChip should have the provided selectedColor.
+ expect(
+ getMaterialBox(tester, find.byType(RawChip).first),
+ paints..rrect(color: selectedColor),
+ );
+ // Enabled & selected elevated FilterChip should have the provided selectedColor.
+ expect(
+ getMaterialBox(tester, find.byType(RawChip).last),
+ paints..rrect(color: selectedColor),
+ );
+ });
+
testWidgets('FilterChip can be tapped', (WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
diff --git a/packages/flutter/test/material/flexible_space_bar_test.dart b/packages/flutter/test/material/flexible_space_bar_test.dart
index 73c4ed8..7477480 100644
--- a/packages/flutter/test/material/flexible_space_bar_test.dart
+++ b/packages/flutter/test/material/flexible_space_bar_test.dart
@@ -801,14 +801,29 @@
));
expect(RenderRebuildTracker.count, 1);
+ expect(
+ tester.layers.lastWhere((Layer element) => element is OpacityLayer),
+ isA<OpacityLayer>().having((OpacityLayer p0) => p0.alpha, 'alpha', 255),
+ );
// We drag up to fully collapse the space bar.
- for (int i = 0; i < 20; i++) {
+ for (int i = 0; i < 9; i++) {
+ await tester.drag(find.byKey(SubCategoryScreenView.scrollKey), const Offset(0, -50.0));
+ await tester.pumpAndSettle();
+ }
+
+ expect(
+ tester.layers.lastWhere((Layer element) => element is OpacityLayer),
+ isA<OpacityLayer>().having((OpacityLayer p0) => p0.alpha, 'alpha', lessThan(255)),
+ );
+
+ for (int i = 0; i < 11; i++) {
await tester.drag(find.byKey(SubCategoryScreenView.scrollKey), const Offset(0, -50.0));
await tester.pumpAndSettle();
}
expect(RenderRebuildTracker.count, greaterThan(1));
+ expect(tester.layers.whereType<OpacityLayer>(), isEmpty);
});
}
diff --git a/packages/flutter/test/material/icon_button_test.dart b/packages/flutter/test/material/icon_button_test.dart
index 6ca92b5..949a467 100644
--- a/packages/flutter/test/material/icon_button_test.dart
+++ b/packages/flutter/test/material/icon_button_test.dart
@@ -789,7 +789,7 @@
await tester.pumpWidget(
wrap(
- useMaterial3: theme.useMaterial3,
+ useMaterial3: false,
child: Column(
children: <Widget>[
IconButton(
diff --git a/packages/flutter/test/material/ink_sparkle_test.dart b/packages/flutter/test/material/ink_sparkle_test.dart
index 6a76bb9..6fea324 100644
--- a/packages/flutter/test/material/ink_sparkle_test.dart
+++ b/packages/flutter/test/material/ink_sparkle_test.dart
@@ -116,6 +116,7 @@
final Key buttonKey = UniqueKey();
await tester.pumpWidget(MaterialApp(
+ theme: ThemeData(useMaterial3: false),
home: Scaffold(
body: Center(
child: RepaintBoundary(
diff --git a/packages/flutter/test/material/input_chip_test.dart b/packages/flutter/test/material/input_chip_test.dart
index a42ae2f..827ded8 100644
--- a/packages/flutter/test/material/input_chip_test.dart
+++ b/packages/flutter/test/material/input_chip_test.dart
@@ -13,7 +13,7 @@
TextDirection textDirection = TextDirection.ltr,
double textScaleFactor = 1.0,
Brightness brightness = Brightness.light,
- bool useMaterial3 = false,
+ bool? useMaterial3,
}) {
return MaterialApp(
theme: ThemeData(brightness: brightness, useMaterial3: useMaterial3),
@@ -101,6 +101,101 @@
}
void main() {
+ testWidgets('InputChip.color resolves material states', (WidgetTester tester) async {
+ const Color disabledSelectedColor = Color(0xffffff00);
+ const Color disabledColor = Color(0xff00ff00);
+ const Color backgroundColor = Color(0xff0000ff);
+ const Color selectedColor = Color(0xffff0000);
+ Widget buildApp({ required bool enabled, required bool selected }) {
+ return wrapForChip(
+ useMaterial3: true,
+ child: InputChip(
+ onSelected: enabled ? (bool value) { } : null,
+ selected: selected,
+ color: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
+ if (states.contains(MaterialState.disabled) && states.contains(MaterialState.selected)) {
+ return disabledSelectedColor;
+ }
+ if (states.contains(MaterialState.disabled)) {
+ return disabledColor;
+ }
+ if (states.contains(MaterialState.selected)) {
+ return selectedColor;
+ }
+ return backgroundColor;
+ }),
+ label: const Text('InputChip'),
+ ),
+ );
+ }
+
+ // Test enabled chip.
+ await tester.pumpWidget(buildApp(enabled: true, selected: false));
+
+ // Enabled chip should have the provided backgroundColor.
+ expect(getMaterialBox(tester), paints..rrect(color: backgroundColor));
+
+ // Test disabled chip.
+ await tester.pumpWidget(buildApp(enabled: false, selected: false));
+ await tester.pumpAndSettle();
+
+ // Disabled chip should have the provided disabledColor.
+ expect(getMaterialBox(tester), paints..rrect(color: disabledColor));
+
+ // Test enabled & selected chip.
+ await tester.pumpWidget(buildApp(enabled: true, selected: true));
+ await tester.pumpAndSettle();
+
+ // Enabled & selected chip should have the provided selectedColor.
+ expect(getMaterialBox(tester), paints..rrect(color: selectedColor));
+
+ // Test disabled & selected chip.
+ await tester.pumpWidget(buildApp(enabled: false, selected: true));
+ await tester.pumpAndSettle();
+
+ // Disabled & selected chip should have the provided disabledSelectedColor.
+ expect(getMaterialBox(tester), paints..rrect(color: disabledSelectedColor));
+ });
+
+ testWidgets('InputChip uses provided state color properties', (WidgetTester tester) async {
+ const Color disabledColor = Color(0xff00ff00);
+ const Color backgroundColor = Color(0xff0000ff);
+ const Color selectedColor = Color(0xffff0000);
+ Widget buildApp({ required bool enabled, required bool selected }) {
+ return wrapForChip(
+ useMaterial3: true,
+ child: InputChip(
+ onSelected: enabled ? (bool value) { } : null,
+ selected: selected,
+ disabledColor: disabledColor,
+ backgroundColor: backgroundColor,
+ selectedColor: selectedColor,
+ label: const Text('InputChip'),
+ ),
+ );
+ }
+
+ // Test enabled chip.
+ await tester.pumpWidget(buildApp(enabled: true, selected: false));
+
+ // Enabled chip should have the provided backgroundColor.
+ expect(getMaterialBox(tester), paints..rrect(color: backgroundColor));
+
+ // Test disabled chip.
+ await tester.pumpWidget(buildApp(enabled: false, selected: false));
+ await tester.pumpAndSettle();
+
+ // Disabled chip should have the provided disabledColor.
+ expect(getMaterialBox(tester), paints..rrect(color: disabledColor));
+
+ // Test enabled & selected chip.
+ await tester.pumpWidget(buildApp(enabled: true, selected: true));
+ await tester.pumpAndSettle();
+
+ // Enabled & selected chip should have the provided selectedColor.
+ expect(getMaterialBox(tester), paints..rrect(color: selectedColor));
+ });
+
testWidgets('InputChip can be tapped', (WidgetTester tester) async {
await tester.pumpWidget(
const MaterialApp(
diff --git a/packages/flutter/test/material/input_decorator_test.dart b/packages/flutter/test/material/input_decorator_test.dart
index c576746..7755053 100644
--- a/packages/flutter/test/material/input_decorator_test.dart
+++ b/packages/flutter/test/material/input_decorator_test.dart
@@ -1643,6 +1643,47 @@
expect(tester.getBottomLeft(find.text(kHelper1)), const Offset(12.0, 76.0));
});
+ testWidgets('InputDecorator shows error text', (WidgetTester tester) async {
+ await tester.pumpWidget(
+ buildInputDecorator(
+ useMaterial3: useMaterial3,
+ decoration: const InputDecoration(
+ errorText: 'errorText',
+ ),
+ ),
+ );
+
+ expect(find.text('errorText'), findsOneWidget);
+ });
+
+ testWidgets('InputDecorator shows error widget', (WidgetTester tester) async {
+ await tester.pumpWidget(
+ buildInputDecorator(
+ useMaterial3: useMaterial3,
+ decoration: const InputDecoration(
+ error: Text('error', style: TextStyle(fontSize: 20.0)),
+ ),
+ ),
+ );
+
+ expect(find.text('error'), findsOneWidget);
+ });
+
+ testWidgets('InputDecorator throws when error text and error widget are provided', (WidgetTester tester) async {
+ expect(
+ () {
+ buildInputDecorator(
+ useMaterial3: useMaterial3,
+ decoration: InputDecoration(
+ errorText: 'errorText',
+ error: const Text('error', style: TextStyle(fontSize: 20.0)),
+ ),
+ );
+ },
+ throwsAssertionError,
+ );
+ });
+
testWidgets('InputDecorator prefix/suffix texts', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
@@ -3924,6 +3965,108 @@
expect(copy.fillColor, Colors.blue);
});
+ test('InputDecorationTheme merge', () {
+ const InputDecorationTheme overrideTheme = InputDecorationTheme(
+ labelStyle: TextStyle(color: Color(0x000000f0)),
+ floatingLabelStyle: TextStyle(color: Color(0x000000f1)),
+ helperStyle: TextStyle(color: Color(0x000000f2)),
+ helperMaxLines: 1,
+ hintStyle: TextStyle(color: Color(0x000000f3)),
+ errorStyle: TextStyle(color: Color(0x000000f4)),
+ errorMaxLines: 1,
+ floatingLabelBehavior: FloatingLabelBehavior.never,
+ floatingLabelAlignment: FloatingLabelAlignment.center,
+ isDense: true,
+ contentPadding: EdgeInsets.all(1.0),
+ isCollapsed: true,
+ iconColor: Color(0x000000f5),
+ prefixStyle: TextStyle(color: Color(0x000000f6)),
+ prefixIconColor: Color(0x000000f7),
+ suffixStyle: TextStyle(color: Color(0x000000f8)),
+ suffixIconColor: Color(0x000000f9),
+ counterStyle: TextStyle(color: Color(0x00000f10)),
+ filled: true,
+ fillColor: Color(0x00000f11),
+ activeIndicatorBorder: BorderSide(
+ color: Color(0x00000f12),
+ ),
+ outlineBorder: BorderSide(
+ color: Color(0x00000f13),
+ ),
+ focusColor: Color(0x00000f14),
+ hoverColor: Color(0x00000f15),
+ errorBorder: OutlineInputBorder(
+ borderRadius: BorderRadius.all(Radius.circular(2.0)),
+ ),
+ focusedBorder: OutlineInputBorder(
+ borderSide: BorderSide(
+ color: Color(0x00000f16),
+ ),
+ ),
+ focusedErrorBorder: OutlineInputBorder(
+ borderSide: BorderSide(
+ color: Color(0x00000f17),
+ ),
+ ),
+ disabledBorder: OutlineInputBorder(
+ borderSide: BorderSide(
+ color: Color(0x00000f18),
+ ),
+ ),
+ enabledBorder: OutlineInputBorder(
+ borderSide: BorderSide(
+ color: Color(0x00000f19),
+ ),
+ ),
+ border: OutlineInputBorder(
+ borderSide: BorderSide(
+ color: Color(0x00000f20),
+ ),
+ ),
+ alignLabelWithHint: true,
+ constraints: BoxConstraints(
+ minHeight: 1.0,
+ minWidth: 1.0,
+ ),
+ );
+
+ final InputDecorationTheme inputDecorationTheme = ThemeData().inputDecorationTheme;
+ final InputDecorationTheme merged = inputDecorationTheme.merge(overrideTheme);
+
+ expect(merged.labelStyle, overrideTheme.labelStyle);
+ expect(merged.floatingLabelStyle, overrideTheme.floatingLabelStyle);
+ expect(merged.helperStyle, overrideTheme.helperStyle);
+ expect(merged.helperMaxLines, overrideTheme.helperMaxLines);
+ expect(merged.hintStyle, overrideTheme.hintStyle);
+ expect(merged.errorStyle, overrideTheme.errorStyle);
+ expect(merged.errorMaxLines, overrideTheme.errorMaxLines);
+ expect(merged.floatingLabelBehavior, isNot(overrideTheme.floatingLabelBehavior));
+ expect(merged.floatingLabelAlignment, isNot(overrideTheme.floatingLabelAlignment));
+ expect(merged.isDense, isNot(overrideTheme.isDense));
+ expect(merged.contentPadding, overrideTheme.contentPadding);
+ expect(merged.isCollapsed, isNot(overrideTheme.isCollapsed));
+ expect(merged.iconColor, overrideTheme.iconColor);
+ expect(merged.prefixStyle, overrideTheme.prefixStyle);
+ expect(merged.prefixIconColor, overrideTheme.prefixIconColor);
+ expect(merged.suffixStyle, overrideTheme.suffixStyle);
+ expect(merged.suffixIconColor, overrideTheme.suffixIconColor);
+ expect(merged.counterStyle, overrideTheme.counterStyle);
+ expect(merged.filled, isNot(overrideTheme.filled));
+ expect(merged.fillColor, overrideTheme.fillColor);
+ expect(merged.activeIndicatorBorder, overrideTheme.activeIndicatorBorder);
+ expect(merged.outlineBorder, overrideTheme.outlineBorder);
+ expect(merged.focusColor, overrideTheme.focusColor);
+ expect(merged.hoverColor, overrideTheme.hoverColor);
+ expect(merged.errorBorder, overrideTheme.errorBorder);
+ expect(merged.focusedBorder, overrideTheme.focusedBorder);
+ expect(merged.focusedErrorBorder, overrideTheme.focusedErrorBorder);
+ expect(merged.disabledBorder, overrideTheme.disabledBorder);
+ expect(merged.enabledBorder, overrideTheme.enabledBorder);
+ expect(merged.border, overrideTheme.border);
+ expect(merged.alignLabelWithHint, isNot(overrideTheme.alignLabelWithHint));
+ expect(merged.constraints, overrideTheme.constraints);
+ });
+
testWidgets('InputDecorationTheme outline border', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
@@ -4189,24 +4332,50 @@
});
testWidgets('InputDecorationTheme.inputDecoration', (WidgetTester tester) async {
- const TextStyle themeStyle = TextStyle(color: Colors.green);
- const TextStyle decorationStyle = TextStyle(color: Colors.blue);
+ const TextStyle themeStyle = TextStyle(color: Color(0xFF00FFFF));
+ const Color themeColor = Color(0xFF00FF00);
+ const InputBorder themeInputBorder = OutlineInputBorder(
+ borderSide: BorderSide(
+ color: Color(0xFF0000FF),
+ ),
+ );
+ const TextStyle decorationStyle = TextStyle(color: Color(0xFFFFFF00));
+ const Color decorationColor = Color(0xFF0000FF);
+ const InputBorder decorationInputBorder = OutlineInputBorder(
+ borderSide: BorderSide(
+ color: Color(0xFFFF00FF),
+ ),
+ );
// InputDecorationTheme arguments define InputDecoration properties.
InputDecoration decoration = const InputDecoration().applyDefaults(
const InputDecorationTheme(
labelStyle: themeStyle,
+ floatingLabelStyle: themeStyle,
helperStyle: themeStyle,
+ helperMaxLines: 2,
hintStyle: themeStyle,
errorStyle: themeStyle,
+ errorMaxLines: 2,
+ floatingLabelBehavior: FloatingLabelBehavior.never,
+ floatingLabelAlignment: FloatingLabelAlignment.center,
isDense: true,
contentPadding: EdgeInsets.all(1.0),
+ iconColor: themeColor,
prefixStyle: themeStyle,
+ prefixIconColor: themeColor,
suffixStyle: themeStyle,
+ suffixIconColor: themeColor,
counterStyle: themeStyle,
filled: true,
- fillColor: Colors.red,
- focusColor: Colors.blue,
+ fillColor: themeColor,
+ focusColor: themeColor,
+ hoverColor: themeColor,
+ errorBorder: themeInputBorder,
+ focusedBorder: themeInputBorder,
+ focusedErrorBorder: themeInputBorder,
+ disabledBorder: themeInputBorder,
+ enabledBorder: themeInputBorder,
border: InputBorder.none,
alignLabelWithHint: true,
constraints: BoxConstraints(minWidth: 10, maxWidth: 20, minHeight: 30, maxHeight: 40),
@@ -4214,16 +4383,31 @@
);
expect(decoration.labelStyle, themeStyle);
+ expect(decoration.floatingLabelStyle, themeStyle);
expect(decoration.helperStyle, themeStyle);
+ expect(decoration.helperMaxLines, 2);
expect(decoration.hintStyle, themeStyle);
expect(decoration.errorStyle, themeStyle);
+ expect(decoration.errorMaxLines, 2);
+ expect(decoration.floatingLabelBehavior, FloatingLabelBehavior.never);
+ expect(decoration.floatingLabelAlignment, FloatingLabelAlignment.center);
expect(decoration.isDense, true);
expect(decoration.contentPadding, const EdgeInsets.all(1.0));
+ expect(decoration.iconColor, themeColor);
expect(decoration.prefixStyle, themeStyle);
+ expect(decoration.prefixIconColor, themeColor);
expect(decoration.suffixStyle, themeStyle);
+ expect(decoration.suffixIconColor, themeColor);
expect(decoration.counterStyle, themeStyle);
expect(decoration.filled, true);
- expect(decoration.fillColor, Colors.red);
+ expect(decoration.fillColor, themeColor);
+ expect(decoration.focusColor, themeColor);
+ expect(decoration.hoverColor, themeColor);
+ expect(decoration.errorBorder, themeInputBorder);
+ expect(decoration.focusedBorder, themeInputBorder);
+ expect(decoration.focusedErrorBorder, themeInputBorder);
+ expect(decoration.disabledBorder, themeInputBorder);
+ expect(decoration.enabledBorder, themeInputBorder);
expect(decoration.border, InputBorder.none);
expect(decoration.alignLabelWithHint, true);
expect(decoration.constraints, const BoxConstraints(minWidth: 10, maxWidth: 20, minHeight: 30, maxHeight: 40));
@@ -4231,57 +4415,97 @@
// InputDecoration (baseDecoration) defines InputDecoration properties
decoration = const InputDecoration(
labelStyle: decorationStyle,
+ floatingLabelStyle: decorationStyle,
helperStyle: decorationStyle,
+ helperMaxLines: 3,
hintStyle: decorationStyle,
errorStyle: decorationStyle,
+ errorMaxLines: 3,
+ floatingLabelBehavior: FloatingLabelBehavior.always,
+ floatingLabelAlignment: FloatingLabelAlignment.start,
isDense: false,
contentPadding: EdgeInsets.all(4.0),
+ iconColor: decorationColor,
prefixStyle: decorationStyle,
+ prefixIconColor: decorationColor,
suffixStyle: decorationStyle,
+ suffixIconColor: decorationColor,
counterStyle: decorationStyle,
filled: false,
- fillColor: Colors.blue,
+ fillColor: decorationColor,
+ focusColor: decorationColor,
+ hoverColor: decorationColor,
+ errorBorder: decorationInputBorder,
+ focusedBorder: decorationInputBorder,
+ focusedErrorBorder: decorationInputBorder,
+ disabledBorder: decorationInputBorder,
+ enabledBorder: decorationInputBorder,
border: OutlineInputBorder(),
alignLabelWithHint: false,
- constraints: BoxConstraints(minWidth: 10, maxWidth: 20, minHeight: 30, maxHeight: 40),
+ constraints: BoxConstraints(minWidth: 40, maxWidth: 50, minHeight: 60, maxHeight: 70),
).applyDefaults(
const InputDecorationTheme(
labelStyle: themeStyle,
+ floatingLabelStyle: themeStyle,
helperStyle: themeStyle,
- helperMaxLines: 5,
+ helperMaxLines: 2,
hintStyle: themeStyle,
errorStyle: themeStyle,
- errorMaxLines: 4,
+ errorMaxLines: 2,
+ floatingLabelBehavior: FloatingLabelBehavior.never,
+ floatingLabelAlignment: FloatingLabelAlignment.center,
isDense: true,
contentPadding: EdgeInsets.all(1.0),
+ iconColor: themeColor,
prefixStyle: themeStyle,
+ prefixIconColor: themeColor,
suffixStyle: themeStyle,
+ suffixIconColor: themeColor,
counterStyle: themeStyle,
filled: true,
- fillColor: Colors.red,
- focusColor: Colors.blue,
+ fillColor: themeColor,
+ focusColor: themeColor,
+ hoverColor: themeColor,
+ errorBorder: themeInputBorder,
+ focusedBorder: themeInputBorder,
+ focusedErrorBorder: themeInputBorder,
+ disabledBorder: themeInputBorder,
+ enabledBorder: themeInputBorder,
border: InputBorder.none,
alignLabelWithHint: true,
- constraints: BoxConstraints(minWidth: 40, maxWidth: 30, minHeight: 20, maxHeight: 10),
+ constraints: BoxConstraints(minWidth: 10, maxWidth: 20, minHeight: 30, maxHeight: 40),
),
);
expect(decoration.labelStyle, decorationStyle);
+ expect(decoration.floatingLabelStyle, decorationStyle);
expect(decoration.helperStyle, decorationStyle);
- expect(decoration.helperMaxLines, 5);
+ expect(decoration.helperMaxLines, 3);
expect(decoration.hintStyle, decorationStyle);
expect(decoration.errorStyle, decorationStyle);
- expect(decoration.errorMaxLines, 4);
+ expect(decoration.errorMaxLines, 3);
+ expect(decoration.floatingLabelBehavior, FloatingLabelBehavior.always);
+ expect(decoration.floatingLabelAlignment, FloatingLabelAlignment.start);
expect(decoration.isDense, false);
expect(decoration.contentPadding, const EdgeInsets.all(4.0));
+ expect(decoration.iconColor, decorationColor);
expect(decoration.prefixStyle, decorationStyle);
+ expect(decoration.prefixIconColor, decorationColor);
expect(decoration.suffixStyle, decorationStyle);
+ expect(decoration.suffixIconColor, decorationColor);
expect(decoration.counterStyle, decorationStyle);
expect(decoration.filled, false);
- expect(decoration.fillColor, Colors.blue);
+ expect(decoration.fillColor, decorationColor);
+ expect(decoration.focusColor, decorationColor);
+ expect(decoration.hoverColor, decorationColor);
+ expect(decoration.errorBorder, decorationInputBorder);
+ expect(decoration.focusedBorder, decorationInputBorder);
+ expect(decoration.focusedErrorBorder, decorationInputBorder);
+ expect(decoration.disabledBorder, decorationInputBorder);
+ expect(decoration.enabledBorder, decorationInputBorder);
expect(decoration.border, const OutlineInputBorder());
expect(decoration.alignLabelWithHint, false);
- expect(decoration.constraints, const BoxConstraints(minWidth: 10, maxWidth: 20, minHeight: 30, maxHeight: 40));
+ expect(decoration.constraints, const BoxConstraints(minWidth: 40, maxWidth: 50, minHeight: 60, maxHeight: 70));
});
testWidgets('InputDecorationTheme.inputDecoration with MaterialState', (WidgetTester tester) async {
@@ -4488,6 +4712,7 @@
// This is a regression test for https://github.com/flutter/flutter/issues/82321
Widget buildFrame(TextDirection textDirection) {
return MaterialApp(
+ theme: ThemeData(useMaterial3: false),
home: Scaffold(
body: Container(
padding: const EdgeInsets.all(16.0),
@@ -4536,6 +4761,7 @@
Widget buildFrame(TextDirection textDirection) {
return MaterialApp(
+ theme: ThemeData(useMaterial3: false),
home: Scaffold(
body: Container(
padding: const EdgeInsets.all(16.0),
@@ -5032,7 +5258,6 @@
useMaterial3: useMaterial3,
// isFocused: false (default)
decoration: const InputDecoration(
- // errorText: false (default)
enabled: false,
errorBorder: errorBorder,
focusedBorder: focusedBorder,
@@ -6291,5 +6516,35 @@
final Text hintTextWidget = tester.widget(hintTextFinder);
expect(hintTextWidget.style!.overflow, decoration.hintStyle!.overflow);
});
+
+ testWidgets('prefixIcon in RTL with asymmetric padding', (WidgetTester tester) async {
+ // Regression test for https://github.com/flutter/flutter/issues/129591
+ const InputDecoration decoration = InputDecoration(
+ contentPadding: EdgeInsetsDirectional.only(end: 24),
+ prefixIcon: Focus(child: Icon(Icons.search)),
+ );
+
+ await tester.pumpWidget(
+ buildInputDecorator(
+ useMaterial3: useMaterial3,
+ // isEmpty: false (default)
+ // isFocused: false (default)
+ decoration: decoration,
+ textDirection: TextDirection.rtl,
+ ),
+ );
+ await tester.pumpAndSettle();
+
+ expect(find.byType(InputDecorator), findsOneWidget);
+ expect(find.byType(Icon), findsOneWidget);
+
+ final Offset(dx: double decoratorRight) =
+ tester.getTopRight(find.byType(InputDecorator));
+ final Offset(dx: double prefixRight) =
+ tester.getTopRight(find.byType(Icon));
+
+ // The prefix is inside the decorator.
+ expect(decoratorRight, lessThanOrEqualTo(prefixRight));
+ });
}
}
diff --git a/packages/flutter/test/material/localizations_test.dart b/packages/flutter/test/material/localizations_test.dart
index d528cc7..67df019 100644
--- a/packages/flutter/test/material/localizations_test.dart
+++ b/packages/flutter/test/material/localizations_test.dart
@@ -28,6 +28,7 @@
expect(localizations.continueButtonLabel, isNotNull);
expect(localizations.copyButtonLabel, isNotNull);
expect(localizations.cutButtonLabel, isNotNull);
+ expect(localizations.scanTextButtonLabel, isNotNull);
expect(localizations.okButtonLabel, isNotNull);
expect(localizations.pasteButtonLabel, isNotNull);
expect(localizations.selectAllButtonLabel, isNotNull);
diff --git a/packages/flutter/test/material/material_test.dart b/packages/flutter/test/material/material_test.dart
index ba8a399..f08733a 100644
--- a/packages/flutter/test/material/material_test.dart
+++ b/packages/flutter/test/material/material_test.dart
@@ -924,6 +924,7 @@
final Key painterKey = UniqueKey();
await tester.pumpWidget(MaterialApp(
+ theme: ThemeData(useMaterial3: false),
home: Scaffold(
body: RepaintBoundary(
key: painterKey,
@@ -962,6 +963,7 @@
final Key painterKey = UniqueKey();
await tester.pumpWidget(MaterialApp(
+ theme: ThemeData(useMaterial3: false),
home: Scaffold(
body: RepaintBoundary(
key: painterKey,
diff --git a/packages/flutter/test/material/menu_anchor_test.dart b/packages/flutter/test/material/menu_anchor_test.dart
index 6e3441e..e48e855 100644
--- a/packages/flutter/test/material/menu_anchor_test.dart
+++ b/packages/flutter/test/material/menu_anchor_test.dart
@@ -3256,9 +3256,4 @@
final String acceleratorLabel;
// Strip the accelerator markers.
String get label => MenuAcceleratorLabel.stripAcceleratorMarkers(acceleratorLabel);
- int get acceleratorIndex {
- int index = -1;
- MenuAcceleratorLabel.stripAcceleratorMarkers(acceleratorLabel, setIndex: (int i) => index = i);
- return index;
- }
}
diff --git a/packages/flutter/test/material/mergeable_material_test.dart b/packages/flutter/test/material/mergeable_material_test.dart
index 2e37bff..08b3fc7 100644
--- a/packages/flutter/test/material/mergeable_material_test.dart
+++ b/packages/flutter/test/material/mergeable_material_test.dart
@@ -1088,6 +1088,75 @@
matches(getBorderRadius(tester, 1), RadiusType.Round, RadiusType.Round);
});
+ testWidgets('MergeableMaterial insert and separate slice', (WidgetTester tester) async {
+ await tester.pumpWidget(
+ const MaterialApp(
+ home: Scaffold(
+ body: SingleChildScrollView(
+ child: MergeableMaterial(
+ children: <MergeableMaterialItem>[
+ MaterialSlice(
+ key: ValueKey<String>('A'),
+ child: SizedBox(
+ width: 100.0,
+ height: 100.0,
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ ),
+ );
+
+ final RenderBox box = tester.renderObject(find.byType(MergeableMaterial));
+ expect(box.size.height, equals(100));
+
+ matches(getBorderRadius(tester, 0), RadiusType.Round, RadiusType.Round);
+
+ await tester.pumpWidget(
+ const MaterialApp(
+ home: Scaffold(
+ body: SingleChildScrollView(
+ child: MergeableMaterial(
+ children: <MergeableMaterialItem>[
+ MaterialSlice(
+ key: ValueKey<String>('A'),
+ child: SizedBox(
+ width: 100.0,
+ height: 100.0,
+ ),
+ ),
+ MaterialGap(
+ key: ValueKey<String>('x'),
+ ),
+ MaterialSlice(
+ key: ValueKey<String>('B'),
+ child: SizedBox(
+ width: 100.0,
+ height: 100.0,
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ ),
+ );
+
+ await tester.pump(const Duration(milliseconds: 100));
+ expect(box.size.height, lessThan(216));
+
+ matches(getBorderRadius(tester, 0), RadiusType.Round, RadiusType.Shifting);
+ matches(getBorderRadius(tester, 1), RadiusType.Shifting, RadiusType.Round);
+
+ await tester.pump(const Duration(milliseconds: 100));
+ expect(box.size.height, equals(216));
+
+ matches(getBorderRadius(tester, 0), RadiusType.Round, RadiusType.Round);
+ matches(getBorderRadius(tester, 1), RadiusType.Round, RadiusType.Round);
+ });
+
bool isDivider(BoxDecoration decoration, bool top, bool bottom) {
const BorderSide side = BorderSide(color: Color(0x1F000000), width: 0.5);
diff --git a/packages/flutter/test/material/navigation_drawer_test.dart b/packages/flutter/test/material/navigation_drawer_test.dart
index 91f68df..cde4e4e 100644
--- a/packages/flutter/test/material/navigation_drawer_test.dart
+++ b/packages/flutter/test/material/navigation_drawer_test.dart
@@ -115,7 +115,7 @@
});
testWidgets(
- 'M3 NavigationDrawer uses proper defaults when no parameters are given',
+ 'NavigationDrawer uses proper defaults when no parameters are given',
(WidgetTester tester) async {
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
final ThemeData theme = ThemeData(useMaterial3: true);
@@ -125,13 +125,13 @@
NavigationDrawer(
children: <Widget>[
Text('Headline', style: theme.textTheme.bodyLarge),
- NavigationDrawerDestination(
- icon: Icon(Icons.ac_unit, color: theme.iconTheme.color),
- label: Text('AC', style: theme.textTheme.bodySmall),
+ const NavigationDrawerDestination(
+ icon: Icon(Icons.ac_unit),
+ label: Text('AC'),
),
- NavigationDrawerDestination(
- icon: Icon(Icons.access_alarm, color: theme.iconTheme.color),
- label: Text('Alarm', style: theme.textTheme.bodySmall),
+ const NavigationDrawerDestination(
+ icon: Icon(Icons.access_alarm),
+ label: Text('Alarm'),
),
],
onDestinationSelected: (int i) {},
@@ -142,11 +142,25 @@
scaffoldKey.currentState!.openDrawer();
await tester.pump(const Duration(seconds: 1));
+ // Test drawer Material.
expect(_getMaterial(tester).color, theme.colorScheme.surface);
expect(_getMaterial(tester).surfaceTintColor, theme.colorScheme.surfaceTint);
+ expect(_getMaterial(tester).shadowColor, Colors.transparent);
expect(_getMaterial(tester).elevation, 1);
+ // Test indicator decoration.
expect(_getIndicatorDecoration(tester)?.color, theme.colorScheme.secondaryContainer);
expect(_getIndicatorDecoration(tester)?.shape, const StadiumBorder());
+ // Test selected and unselected icon colors.
+ expect(_iconStyle(tester, Icons.ac_unit)?.color, theme.colorScheme.onSecondaryContainer);
+ expect(_iconStyle(tester, Icons.access_alarm)?.color, theme.colorScheme.onSurfaceVariant);
+ // Test selected and unselected label colors.
+ expect(_labelStyle(tester, 'AC')?.color, theme.colorScheme.onSecondaryContainer);
+ expect(_labelStyle(tester, 'Alarm')?.color, theme.colorScheme.onSurfaceVariant);
+ // Test that the icon and label are the correct size.
+ RenderBox iconBox = tester.renderObject(find.byIcon(Icons.ac_unit));
+ expect(iconBox.size, const Size(24.0, 24.0));
+ iconBox = tester.renderObject(find.byIcon(Icons.access_alarm));
+ expect(iconBox.size, const Size(24.0, 24.0));
});
testWidgets('Navigation drawer is scrollable', (WidgetTester tester) async {
@@ -418,6 +432,20 @@
.decoration as ShapeDecoration?;
}
+TextStyle? _iconStyle(WidgetTester tester, IconData icon) {
+ final RichText iconRichText = tester.widget<RichText>(
+ find.descendant(of: find.byIcon(icon), matching: find.byType(RichText)),
+ );
+ return iconRichText.text.style;
+}
+
+TextStyle? _labelStyle(WidgetTester tester, String label) {
+ final RichText labelRichText = tester.widget<RichText>(
+ find.descendant(of: find.text(label), matching: find.byType(RichText)),
+ );
+ return labelRichText.text.style;
+}
+
void widgetSetup(WidgetTester tester, double viewWidth, {double viewHeight = 1000}) {
tester.view.devicePixelRatio = 2;
final double dpi = tester.view.devicePixelRatio;
diff --git a/packages/flutter/test/material/page_test.dart b/packages/flutter/test/material/page_test.dart
index 5310250..b0486a9 100644
--- a/packages/flutter/test/material/page_test.dart
+++ b/packages/flutter/test/material/page_test.dart
@@ -252,6 +252,7 @@
RepaintBoundary(
key: key,
child: MaterialApp(
+ theme: ThemeData(useMaterial3: false),
onGenerateRoute: (RouteSettings settings) {
return MaterialPageRoute<void>(
builder: (BuildContext context) {
diff --git a/packages/flutter/test/material/progress_indicator_test.dart b/packages/flutter/test/material/progress_indicator_test.dart
index fdf268f..c68e350 100644
--- a/packages/flutter/test/material/progress_indicator_test.dart
+++ b/packages/flutter/test/material/progress_indicator_test.dart
@@ -723,7 +723,10 @@
final AnimationSheetBuilder animationSheet = AnimationSheetBuilder(frameSize: const Size(50, 50));
await tester.pumpFrames(animationSheet.record(
- const _RefreshProgressIndicatorGolden(),
+ Theme(
+ data: ThemeData(useMaterial3: false),
+ child: const _RefreshProgressIndicatorGolden()
+ ),
), const Duration(seconds: 3));
await expectLater(
@@ -1001,11 +1004,14 @@
final AnimationSheetBuilder animationSheet = AnimationSheetBuilder(frameSize: const Size(40, 40));
await tester.pumpFrames(animationSheet.record(
- const Directionality(
- textDirection: TextDirection.ltr,
- child: Padding(
- padding: EdgeInsets.all(4),
- child: CircularProgressIndicator(),
+ Theme(
+ data: ThemeData(useMaterial3: false),
+ child: const Directionality(
+ textDirection: TextDirection.ltr,
+ child: Padding(
+ padding: EdgeInsets.all(4),
+ child: CircularProgressIndicator(),
+ ),
),
),
), const Duration(seconds: 2));
diff --git a/packages/flutter/test/material/radio_list_tile_test.dart b/packages/flutter/test/material/radio_list_tile_test.dart
index f94c18c..b5c5550 100644
--- a/packages/flutter/test/material/radio_list_tile_test.dart
+++ b/packages/flutter/test/material/radio_list_tile_test.dart
@@ -1012,12 +1012,11 @@
);
});
- testWidgets('RadioListTile respects hoverColor', (WidgetTester tester) async {
+ testWidgets('Material3 - RadioListTile respects hoverColor', (WidgetTester tester) async {
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
int? groupValue = 0;
final Color? hoverColor = Colors.orange[500];
- final ThemeData theme = ThemeData();
- final bool material3 = theme.useMaterial3;
+ final ThemeData theme = ThemeData(useMaterial3: true);
Widget buildApp({bool enabled = true}) {
return wrap(
child: MaterialApp(
@@ -1045,8 +1044,8 @@
Material.of(tester.element(find.byType(Radio<int>))),
paints
..rect()
- ..circle(color: material3 ? theme.colorScheme.primary : const Color(0xff2196f3))
- ..circle(color: material3 ? theme.colorScheme.primary : const Color(0xff2196f3)),
+ ..circle(color: theme.colorScheme.primary)
+ ..circle(color: theme.colorScheme.primary),
);
// Start hovering
@@ -1074,12 +1073,12 @@
Material.of(tester.element(find.byType(Radio<int>))),
paints
..rect()
- ..circle(color: material3 ? theme.colorScheme.onSurface.withOpacity(0.38) : const Color(0x61000000))
- ..circle(color: material3 ? theme.colorScheme.onSurface.withOpacity(0.38) : const Color(0x61000000)),
+ ..circle(color: theme.colorScheme.onSurface.withOpacity(0.38))
+ ..circle(color: theme.colorScheme.onSurface.withOpacity(0.38)),
);
});
- testWidgets('RadioListTile respects overlayColor in active/pressed/hovered states', (WidgetTester tester) async {
+ testWidgets('Material3 - RadioListTile respects overlayColor in active/pressed/hovered states', (WidgetTester tester) async {
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
const Color fillColor = Color(0xFF000000);
@@ -1101,13 +1100,11 @@
return null;
}
- final ThemeData theme = ThemeData();
- final bool material3 = theme.useMaterial3;
Widget buildRadio({bool active = false, bool useOverlay = true}) {
- return wrap(
- child: MaterialApp(
- theme: theme,
- home: RadioListTile<bool>(
+ return MaterialApp(
+ theme: ThemeData(useMaterial3: true),
+ home: Material(
+ child: RadioListTile<bool>(
value: active,
groupValue: true,
onChanged: (_) { },
@@ -1125,13 +1122,13 @@
expect(
Material.of(tester.element(find.byType(Radio<bool>))),
- material3 ? (paints..circle(
- color: fillColor.withAlpha(kRadialReactionAlpha),
- radius: 20,
- )) : (paints..circle()..circle(
- color: fillColor.withAlpha(kRadialReactionAlpha),
- radius: 20,
- )),
+ paints
+ ..rect(color: const Color(0x00000000))
+ ..rect(color: const Color(0x66bcbcbc))
+ ..circle(
+ color: fillColor.withAlpha(kRadialReactionAlpha),
+ radius: 20.0,
+ ),
reason: 'Default inactive pressed Radio should have overlay color from fillColor',
);
@@ -1141,13 +1138,13 @@
expect(
Material.of(tester.element(find.byType(Radio<bool>))),
- material3 ? (paints..circle(
- color: fillColor.withAlpha(kRadialReactionAlpha),
- radius: 20,
- )) : (paints..circle()..circle(
- color: fillColor.withAlpha(kRadialReactionAlpha),
- radius: 20,
- )),
+ paints
+ ..rect(color: const Color(0x00000000))
+ ..rect(color: const Color(0x66bcbcbc))
+ ..circle(
+ color: fillColor.withAlpha(kRadialReactionAlpha),
+ radius: 20.0,
+ ),
reason: 'Default active pressed Radio should have overlay color from fillColor',
);
@@ -1157,13 +1154,13 @@
expect(
Material.of(tester.element(find.byType(Radio<bool>))),
- material3 ? (paints..circle(
- color: inactivePressedOverlayColor,
- radius: 20,
- )) : (paints..circle()..circle(
- color: inactivePressedOverlayColor,
- radius: 20,
- )),
+ paints
+ ..rect(color: const Color(0x00000000))
+ ..rect(color: const Color(0x66bcbcbc))
+ ..circle(
+ color: inactivePressedOverlayColor,
+ radius: 20.0,
+ ),
reason: 'Inactive pressed Radio should have overlay color: $inactivePressedOverlayColor',
);
@@ -1173,17 +1170,17 @@
expect(
Material.of(tester.element(find.byType(Radio<bool>))),
- material3 ? (paints..circle(
- color: activePressedOverlayColor,
- radius: 20,
- )) : (paints..circle()..circle(
- color: activePressedOverlayColor,
- radius: 20,
- )),
+ paints
+ ..rect(color: const Color(0x00000000))
+ ..rect(color: const Color(0x66bcbcbc))
+ ..circle(
+ color: activePressedOverlayColor,
+ radius: 20.0,
+ ),
reason: 'Active pressed Radio should have overlay color: $activePressedOverlayColor',
);
- // Start hovering
+ // Start hovering.
final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
await gesture.addPointer();
await gesture.moveTo(tester.getCenter(find.byType(Radio<bool>)));
@@ -1195,13 +1192,13 @@
expect(
Material.of(tester.element(find.byType(Radio<bool>))),
- material3 ? (paints..circle(
- color: hoverOverlayColor,
- radius: 20,
- )) : (paints..circle(
- color: hoverOverlayColor,
- radius: 20,
- )),
+ paints
+ ..rect(color: const Color(0x00000000))
+ ..rect(color: const Color(0x0a000000))
+ ..circle(
+ color: hoverOverlayColor,
+ radius: 20.0,
+ ),
reason: 'Hovered Radio should use overlay color $hoverOverlayColor over $hoverColor',
);
});
@@ -1336,4 +1333,179 @@
expect(feedback.hapticCount, 0);
});
});
+
+ group('Material 2', () {
+ // These tests are only relevant for Material 2. Once Material 2
+ // support is deprecated and the APIs are removed, these tests
+ // can be deleted.
+
+ testWidgets('Material2 - RadioListTile respects overlayColor in active/pressed/hovered states', (WidgetTester tester) async {
+ tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
+
+ const Color fillColor = Color(0xFF000000);
+ const Color activePressedOverlayColor = Color(0xFF000001);
+ const Color inactivePressedOverlayColor = Color(0xFF000002);
+ const Color hoverOverlayColor = Color(0xFF000003);
+ const Color hoverColor = Color(0xFF000005);
+
+ Color? getOverlayColor(Set<MaterialState> states) {
+ if (states.contains(MaterialState.pressed)) {
+ if (states.contains(MaterialState.selected)) {
+ return activePressedOverlayColor;
+ }
+ return inactivePressedOverlayColor;
+ }
+ if (states.contains(MaterialState.hovered)) {
+ return hoverOverlayColor;
+ }
+ return null;
+ }
+
+ Widget buildRadio({bool active = false, bool useOverlay = true}) {
+ return MaterialApp(
+ theme: ThemeData(useMaterial3: false),
+ home: Material(
+ child: RadioListTile<bool>(
+ value: active,
+ groupValue: true,
+ onChanged: (_) { },
+ fillColor: const MaterialStatePropertyAll<Color>(fillColor),
+ overlayColor: useOverlay ? MaterialStateProperty.resolveWith(getOverlayColor) : null,
+ hoverColor: hoverColor,
+ ),
+ ),
+ );
+ }
+
+ await tester.pumpWidget(buildRadio(useOverlay: false));
+ await tester.press(find.byType(Radio<bool>));
+ await tester.pumpAndSettle();
+
+ expect(
+ Material.of(tester.element(find.byType(Radio<bool>))),
+ paints
+ ..circle()
+ ..circle(
+ color: fillColor.withAlpha(kRadialReactionAlpha),
+ radius: 20,
+ ),
+ reason: 'Default inactive pressed Radio should have overlay color from fillColor',
+ );
+
+ await tester.pumpWidget(buildRadio(active: true, useOverlay: false));
+ await tester.press(find.byType(Radio<bool>));
+ await tester.pumpAndSettle();
+
+ expect(
+ Material.of(tester.element(find.byType(Radio<bool>))),
+ paints
+ ..circle()
+ ..circle(
+ color: fillColor.withAlpha(kRadialReactionAlpha),
+ radius: 20,
+ ),
+ reason: 'Default active pressed Radio should have overlay color from fillColor',
+ );
+
+ await tester.pumpWidget(buildRadio());
+ await tester.press(find.byType(Radio<bool>));
+ await tester.pumpAndSettle();
+
+ expect(
+ Material.of(tester.element(find.byType(Radio<bool>))),
+ paints
+ ..circle()
+ ..circle(
+ color: inactivePressedOverlayColor,
+ radius: 20,
+ ),
+ reason: 'Inactive pressed Radio should have overlay color: $inactivePressedOverlayColor',
+ );
+
+ // Start hovering.
+ final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
+ await gesture.addPointer();
+ await gesture.moveTo(tester.getCenter(find.byType(Radio<bool>)));
+ await tester.pumpAndSettle();
+
+ await tester.pumpWidget(Container());
+ await tester.pumpWidget(buildRadio());
+ await tester.pumpAndSettle();
+
+ expect(
+ Material.of(tester.element(find.byType(Radio<bool>))),
+ paints
+ ..circle(
+ color: hoverOverlayColor,
+ radius: 20,
+ ),
+ reason: 'Hovered Radio should use overlay color $hoverOverlayColor over $hoverColor',
+ );
+ });
+
+ testWidgets('Material2 - RadioListTile respects hoverColor', (WidgetTester tester) async {
+ tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
+ int? groupValue = 0;
+ final Color? hoverColor = Colors.orange[500];
+ Widget buildApp({bool enabled = true}) {
+ return wrap(
+ child: MaterialApp(
+ theme: ThemeData(useMaterial3: false),
+ home: StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
+ return RadioListTile<int>(
+ value: 0,
+ onChanged: enabled ? (int? newValue) {
+ setState(() {
+ groupValue = newValue;
+ });
+ } : null,
+ hoverColor: hoverColor,
+ groupValue: groupValue,
+ );
+ }),
+ ),
+ );
+ }
+ await tester.pumpWidget(buildApp());
+
+ await tester.pump();
+ await tester.pumpAndSettle();
+ expect(
+ Material.of(tester.element(find.byType(Radio<int>))),
+ paints
+ ..rect()
+ ..circle(color:const Color(0xff2196f3))
+ ..circle(color:const Color(0xff2196f3)),
+ );
+
+ // Start hovering
+ final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
+ await gesture.moveTo(tester.getCenter(find.byType(Radio<int>)));
+
+ // Check when the radio isn't selected.
+ groupValue = 1;
+ await tester.pumpWidget(buildApp());
+ await tester.pump();
+ await tester.pumpAndSettle();
+ expect(
+ Material.of(tester.element(find.byType(Radio<int>))),
+ paints
+ ..rect()
+ ..circle(color: hoverColor)
+ );
+
+ // Check when the radio is selected, but disabled.
+ groupValue = 0;
+ await tester.pumpWidget(buildApp(enabled: false));
+ await tester.pump();
+ await tester.pumpAndSettle();
+ expect(
+ Material.of(tester.element(find.byType(Radio<int>))),
+ paints
+ ..rect()
+ ..circle(color:const Color(0x61000000))
+ ..circle(color:const Color(0x61000000)),
+ );
+ });
+ });
}
diff --git a/packages/flutter/test/material/radio_test.dart b/packages/flutter/test/material/radio_test.dart
index eb1349a..9f4610c 100644
--- a/packages/flutter/test/material/radio_test.dart
+++ b/packages/flutter/test/material/radio_test.dart
@@ -398,7 +398,7 @@
tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler<dynamic>(SystemChannels.accessibility, null);
});
- testWidgets('Radio ink ripple is displayed correctly - M2', (WidgetTester tester) async {
+ testWidgets('Material2 - Radio ink ripple is displayed correctly', (WidgetTester tester) async {
final Key painterKey = UniqueKey();
const Key radioKey = Key('radio');
@@ -428,7 +428,41 @@
await tester.pumpAndSettle();
await expectLater(
find.byKey(painterKey),
- matchesGoldenFile('radio.ink_ripple.png'),
+ matchesGoldenFile('m2_radio.ink_ripple.png'),
+ );
+ });
+
+ testWidgets('Material3 - Radio ink ripple is displayed correctly', (WidgetTester tester) async {
+ final Key painterKey = UniqueKey();
+ const Key radioKey = Key('radio');
+
+ await tester.pumpWidget(MaterialApp(
+ theme: ThemeData(useMaterial3: true),
+ home: Scaffold(
+ body: RepaintBoundary(
+ key: painterKey,
+ child: Center(
+ child: Container(
+ width: 100,
+ height: 100,
+ color: Colors.white,
+ child: Radio<int>(
+ key: radioKey,
+ value: 1,
+ groupValue: 1,
+ onChanged: (int? value) { },
+ ),
+ ),
+ ),
+ ),
+ ),
+ ));
+
+ await tester.press(find.byKey(radioKey));
+ await tester.pumpAndSettle();
+ await expectLater(
+ find.byKey(painterKey),
+ matchesGoldenFile('m3_radio.ink_ripple.png'),
);
});
@@ -469,12 +503,95 @@
);
});
- testWidgets('Radio is focusable and has correct focus color', (WidgetTester tester) async {
+ testWidgets('Material2 - Radio is focusable and has correct focus color', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(debugLabel: 'Radio');
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
int? groupValue = 0;
const Key radioKey = Key('radio');
- final bool material3 = theme.useMaterial3;
+ Widget buildApp({bool enabled = true}) {
+ return MaterialApp(
+ theme: ThemeData(useMaterial3: false),
+ home: Material(
+ child: Center(
+ child: StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
+ return Container(
+ width: 100,
+ height: 100,
+ color: Colors.white,
+ child: Radio<int>(
+ key: radioKey,
+ value: 0,
+ onChanged: enabled ? (int? newValue) {
+ setState(() {
+ groupValue = newValue;
+ });
+ } : null,
+ focusColor: Colors.orange[500],
+ autofocus: true,
+ focusNode: focusNode,
+ groupValue: groupValue,
+ ),
+ );
+ }),
+ ),
+ ),
+ );
+ }
+ await tester.pumpWidget(buildApp());
+
+ await tester.pumpAndSettle();
+ expect(focusNode.hasPrimaryFocus, isTrue);
+ expect(
+ Material.of(tester.element(find.byKey(radioKey))),
+ paints
+ ..rect(
+ color: const Color(0xffffffff),
+ rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0),
+ )
+ ..circle(color: Colors.orange[500])
+ ..circle(color: const Color(0xff2196f3))
+ ..circle(color: const Color(0xff2196f3)),
+ );
+
+ // Check when the radio isn't selected.
+ groupValue = 1;
+ await tester.pumpWidget(buildApp());
+ await tester.pumpAndSettle();
+ expect(focusNode.hasPrimaryFocus, isTrue);
+ expect(
+ Material.of(tester.element(find.byKey(radioKey))),
+ paints
+ ..rect(
+ color: const Color(0xffffffff),
+ rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0),
+ )
+ ..circle(color: Colors.orange[500])
+ ..circle(color: const Color(0x8a000000), style: PaintingStyle.stroke, strokeWidth: 2.0),
+ );
+
+ // Check when the radio is selected, but disabled.
+ groupValue = 0;
+ await tester.pumpWidget(buildApp(enabled: false));
+ await tester.pumpAndSettle();
+ expect(focusNode.hasPrimaryFocus, isFalse);
+ expect(
+ Material.of(tester.element(find.byKey(radioKey))),
+ paints
+ ..rect(
+ color: const Color(0xffffffff),
+ rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0),
+ )
+ ..circle(color: const Color(0x61000000))
+ ..circle(color: const Color(0x61000000)),
+ );
+ });
+
+ testWidgets('Material3 - Radio is focusable and has correct focus color', (WidgetTester tester) async {
+ final FocusNode focusNode = FocusNode(debugLabel: 'Radio');
+ tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
+ int? groupValue = 0;
+ const Key radioKey = Key('radio');
+ final ThemeData theme = ThemeData(useMaterial3: true);
Widget buildApp({bool enabled = true}) {
return MaterialApp(
theme: theme,
@@ -516,8 +633,8 @@
rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0),
)
..circle(color: Colors.orange[500])
- ..circle(color: material3 ? theme.colorScheme.primary : const Color(0xff2196f3))
- ..circle(color: material3 ? theme.colorScheme.primary : const Color(0xff2196f3)),
+ ..circle(color: theme.colorScheme.primary)
+ ..circle(color: theme.colorScheme.primary),
);
// Check when the radio isn't selected.
@@ -527,15 +644,7 @@
expect(focusNode.hasPrimaryFocus, isTrue);
expect(
Material.of(tester.element(find.byKey(radioKey))),
- theme.useMaterial3
- ? (paints..rect()..circle(color: Colors.orange[500])..circle(color: theme.colorScheme.onSurface))
- : (paints
- ..rect(
- color: const Color(0xffffffff),
- rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0),
- )
- ..circle(color: Colors.orange[500])
- ..circle(color: const Color(0x8a000000), style: PaintingStyle.stroke, strokeWidth: 2.0)),
+ paints..rect()..circle(color: Colors.orange[500])..circle(color: theme.colorScheme.onSurface),
);
// Check when the radio is selected, but disabled.
@@ -547,22 +656,21 @@
Material.of(tester.element(find.byKey(radioKey))),
paints
..rect(
- color: const Color(0xffffffff),
- rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0),
- )
- ..circle(color: material3 ? theme.colorScheme.onSurface.withOpacity(0.38) : const Color(0x61000000))
- ..circle(color: material3 ? theme.colorScheme.onSurface.withOpacity(0.38) : const Color(0x61000000)),
+ color: const Color(0xffffffff),
+ rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0),
+ )
+ ..circle(color: theme.colorScheme.onSurface.withOpacity(0.38))
+ ..circle(color: theme.colorScheme.onSurface.withOpacity(0.38)),
);
});
- testWidgets('Radio can be hovered and has correct hover color', (WidgetTester tester) async {
+ testWidgets('Material2 - Radio can be hovered and has correct hover color', (WidgetTester tester) async {
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
int? groupValue = 0;
const Key radioKey = Key('radio');
- final bool material3 = theme.useMaterial3;
Widget buildApp({bool enabled = true}) {
return MaterialApp(
- theme: theme,
+ theme: ThemeData(useMaterial3: false),
home: Material(
child: Center(
child: StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
@@ -598,8 +706,8 @@
color: const Color(0xffffffff),
rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0),
)
- ..circle(color: material3 ? theme.colorScheme.primary : const Color(0xff2196f3))
- ..circle(color: material3 ? theme.colorScheme.primary : const Color(0xff2196f3)),
+ ..circle(color: const Color(0xff2196f3))
+ ..circle(color: const Color(0xff2196f3)),
);
// Start hovering
@@ -619,7 +727,7 @@
rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0),
)
..circle(color: Colors.orange[500])
- ..circle(color: theme.useMaterial3 ? theme.colorScheme.onSurface : const Color(0x8a000000), style: PaintingStyle.stroke, strokeWidth: 2.0),
+ ..circle(color: const Color(0x8a000000), style: PaintingStyle.stroke, strokeWidth: 2.0),
);
// Check when the radio is selected, but disabled.
@@ -634,8 +742,92 @@
color: const Color(0xffffffff),
rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0),
)
- ..circle(color: material3 ? theme.colorScheme.onSurface.withOpacity(0.38) : const Color(0x61000000))
- ..circle(color: material3 ? theme.colorScheme.onSurface.withOpacity(0.38) : const Color(0x61000000)),
+ ..circle(color: const Color(0x61000000))
+ ..circle(color: const Color(0x61000000)),
+ );
+ });
+
+ testWidgets('Material3 - Radio can be hovered and has correct hover color', (WidgetTester tester) async {
+ tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
+ int? groupValue = 0;
+ const Key radioKey = Key('radio');
+ final ThemeData theme = ThemeData(useMaterial3: true);
+ Widget buildApp({bool enabled = true}) {
+ return MaterialApp(
+ theme: theme,
+ home: Material(
+ child: Center(
+ child: StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
+ return Container(
+ width: 100,
+ height: 100,
+ color: Colors.white,
+ child: Radio<int>(
+ key: radioKey,
+ value: 0,
+ onChanged: enabled ? (int? newValue) {
+ setState(() {
+ groupValue = newValue;
+ });
+ } : null,
+ hoverColor: Colors.orange[500],
+ groupValue: groupValue,
+ ),
+ );
+ }),
+ ),
+ ),
+ );
+ }
+ await tester.pumpWidget(buildApp());
+
+ await tester.pump();
+ await tester.pumpAndSettle();
+ expect(
+ Material.of(tester.element(find.byKey(radioKey))),
+ paints
+ ..rect(
+ color: const Color(0xffffffff),
+ rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0),
+ )
+ ..circle(color: theme.colorScheme.primary)
+ ..circle(color: theme.colorScheme.primary),
+ );
+
+ // Start hovering
+ final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
+ await gesture.moveTo(tester.getCenter(find.byKey(radioKey)));
+
+ // Check when the radio isn't selected.
+ groupValue = 1;
+ await tester.pumpWidget(buildApp());
+ await tester.pump();
+ await tester.pumpAndSettle();
+ expect(
+ Material.of(tester.element(find.byKey(radioKey))),
+ paints
+ ..rect(
+ color: const Color(0xffffffff),
+ rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0),
+ )
+ ..circle(color: Colors.orange[500])
+ ..circle(color: theme.colorScheme.onSurface, style: PaintingStyle.stroke, strokeWidth: 2.0),
+ );
+
+ // Check when the radio is selected, but disabled.
+ groupValue = 0;
+ await tester.pumpWidget(buildApp(enabled: false));
+ await tester.pump();
+ await tester.pumpAndSettle();
+ expect(
+ Material.of(tester.element(find.byKey(radioKey))),
+ paints
+ ..rect(
+ color: const Color(0xffffffff),
+ rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0),
+ )
+ ..circle(color: theme.colorScheme.onSurface.withOpacity(0.38))
+ ..circle(color: theme.colorScheme.onSurface.withOpacity(0.38)),
);
});
@@ -951,7 +1143,7 @@
);
});
- testWidgets('Radio fill color resolves in hovered/focused states', (WidgetTester tester) async {
+ testWidgets('Material2 - Radio fill color resolves in hovered/focused states', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(debugLabel: 'radio');
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
const Color hoveredFillColor = Color(0xFF000001);
@@ -967,11 +1159,11 @@
return Colors.transparent;
}
- final MaterialStateProperty<Color> fillColor =
- MaterialStateColor.resolveWith(getFillColor);
+ final MaterialStateProperty<Color> fillColor = MaterialStateColor.resolveWith(getFillColor);
int? groupValue = 0;
const Key radioKey = Key('radio');
+ final ThemeData theme = ThemeData(useMaterial3: false);
Widget buildApp() {
return MaterialApp(
theme: theme,
@@ -1007,15 +1199,13 @@
expect(focusNode.hasPrimaryFocus, isTrue);
expect(
Material.of(tester.element(find.byKey(radioKey))),
- theme.useMaterial3
- ? (paints..rect()..circle(color: theme.colorScheme.primary.withOpacity(0.12))..circle(color: focusedFillColor))
- : (paints
- ..rect(
- color: const Color(0xffffffff),
- rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0),
- )
- ..circle(color: Colors.black12)
- ..circle(color: focusedFillColor)),
+ paints
+ ..rect(
+ color: const Color(0xffffffff),
+ rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0),
+ )
+ ..circle(color: Colors.black12)
+ ..circle(color: focusedFillColor),
);
// Start hovering
@@ -1028,10 +1218,88 @@
Material.of(tester.element(find.byKey(radioKey))),
paints
..rect(
- color: const Color(0xffffffff),
- rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0),
- )
- ..circle(color: theme.useMaterial3 ? theme.colorScheme.primary.withOpacity(0.08) : theme.hoverColor)
+ color: const Color(0xffffffff),
+ rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0),
+ )
+ ..circle(color: theme.hoverColor)
+ ..circle(color: hoveredFillColor),
+ );
+ });
+
+ testWidgets('Material3 - Radio fill color resolves in hovered/focused states', (WidgetTester tester) async {
+ final FocusNode focusNode = FocusNode(debugLabel: 'radio');
+ tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
+ const Color hoveredFillColor = Color(0xFF000001);
+ const Color focusedFillColor = Color(0xFF000002);
+
+ Color getFillColor(Set<MaterialState> states) {
+ if (states.contains(MaterialState.hovered)) {
+ return hoveredFillColor;
+ }
+ if (states.contains(MaterialState.focused)) {
+ return focusedFillColor;
+ }
+ return Colors.transparent;
+ }
+
+ final MaterialStateProperty<Color> fillColor =
+ MaterialStateColor.resolveWith(getFillColor);
+
+ int? groupValue = 0;
+ const Key radioKey = Key('radio');
+ final ThemeData theme = ThemeData(useMaterial3: true);
+ Widget buildApp() {
+ return MaterialApp(
+ theme: theme,
+ home: Material(
+ child: Center(
+ child: StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
+ return Container(
+ width: 100,
+ height: 100,
+ color: Colors.white,
+ child: Radio<int>(
+ autofocus: true,
+ focusNode: focusNode,
+ key: radioKey,
+ value: 0,
+ fillColor: fillColor,
+ onChanged: (int? newValue) {
+ setState(() {
+ groupValue = newValue;
+ });
+ },
+ groupValue: groupValue,
+ ),
+ );
+ }),
+ ),
+ ),
+ );
+ }
+
+ await tester.pumpWidget(buildApp());
+ await tester.pumpAndSettle();
+ expect(focusNode.hasPrimaryFocus, isTrue);
+ expect(
+ Material.of(tester.element(find.byKey(radioKey))),
+ paints..rect()..circle(color: theme.colorScheme.primary.withOpacity(0.12))..circle(color: focusedFillColor),
+ );
+
+ // Start hovering
+ final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
+ await gesture.addPointer();
+ await gesture.moveTo(tester.getCenter(find.byKey(radioKey)));
+ await tester.pumpAndSettle();
+
+ expect(
+ Material.of(tester.element(find.byKey(radioKey))),
+ paints
+ ..rect(
+ color: const Color(0xffffffff),
+ rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0),
+ )
+ ..circle(color: theme.colorScheme.primary.withOpacity(0.08))
..circle(color: hoveredFillColor),
);
});
@@ -1263,11 +1531,10 @@
expect(find.text(tapTooltip), findsOneWidget);
});
- testWidgets('Radio button default colors', (WidgetTester tester) async {
- final bool material3 = theme.useMaterial3;
+ testWidgets('Material2 - Radio button default colors', (WidgetTester tester) async {
Widget buildRadio({bool enabled = true, bool selected = true}) {
return MaterialApp(
- theme: theme,
+ theme: ThemeData(useMaterial3: false),
home: Scaffold(
body: Radio<bool>(
value: true,
@@ -1284,8 +1551,8 @@
expect(
Material.of(tester.element(find.byType(Radio<bool>))),
paints
- ..circle(color: material3 ? theme.colorScheme.primary : const Color(0xFF2196F3)) // Outer circle - primary value
- ..circle(color: material3 ? theme.colorScheme.primary : const Color(0xFF2196F3))..restore(), // Inner circle - primary value
+ ..circle(color: const Color(0xFF2196F3)) // Outer circle - primary value
+ ..circle(color: const Color(0xFF2196F3))..restore(), // Inner circle - primary value
);
await tester.pumpWidget(Container());
@@ -1296,7 +1563,7 @@
Material.of(tester.element(find.byType(Radio<bool>))),
paints
..save()
- ..circle(color: material3 ? theme.colorScheme.primary : const Color(0xFF2196F3))
+ ..circle(color: const Color(0xFF2196F3))
..restore(),
);
@@ -1306,19 +1573,64 @@
expect(
Material.of(tester.element(find.byType(Radio<bool>))),
- theme.useMaterial3
- ? (paints
- ..circle(color: theme.colorScheme.onSurface.withOpacity(0.38)))
- : (paints..circle(color: Colors.black38))
+ paints..circle(color: Colors.black38)
);
});
- testWidgets('Radio button default overlay colors in hover/focus/press states', (WidgetTester tester) async {
+ testWidgets('Material3 - Radio button default colors', (WidgetTester tester) async {
+ final ThemeData theme = ThemeData(useMaterial3: true);
+ Widget buildRadio({bool enabled = true, bool selected = true}) {
+ return MaterialApp(
+ theme: theme,
+ home: Scaffold(
+ body: Radio<bool>(
+ value: true,
+ groupValue: true,
+ onChanged: enabled ? (_) {} : null,
+ ),
+ )
+ );
+ }
+
+ await tester.pumpWidget(buildRadio());
+ await tester.pumpAndSettle();
+
+ expect(
+ Material.of(tester.element(find.byType(Radio<bool>))),
+ paints
+ ..circle(color: theme.colorScheme.primary) // Outer circle - primary value
+ ..circle(color: theme.colorScheme.primary)..restore(), // Inner circle - primary value
+ );
+
+ await tester.pumpWidget(Container());
+ await tester.pumpWidget(buildRadio(selected: false));
+ await tester.pumpAndSettle();
+
+ expect(
+ Material.of(tester.element(find.byType(Radio<bool>))),
+ paints
+ ..save()
+ ..circle(color: theme.colorScheme.primary)
+ ..restore(),
+ );
+
+ await tester.pumpWidget(Container());
+ await tester.pumpWidget(buildRadio(enabled: false));
+ await tester.pumpAndSettle();
+
+ expect(
+ Material.of(tester.element(find.byType(Radio<bool>))),
+ paints
+ ..circle(color: theme.colorScheme.onSurface.withOpacity(0.38))
+ );
+ });
+
+ testWidgets('Material2 - Radio button default overlay colors in hover/focus/press states', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(debugLabel: 'Radio');
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
+ final ThemeData theme = ThemeData(useMaterial3: false);
final ColorScheme colors = theme.colorScheme;
- final bool material3 = theme.useMaterial3;
Widget buildRadio({bool enabled = true, bool focused = false, bool selected = true}) {
return MaterialApp(
theme: theme,
@@ -1339,9 +1651,7 @@
await tester.pumpAndSettle();
expect(
Material.of(tester.element(find.byType(Radio<bool>))),
- material3
- ? (paints..circle(color: colors.primary.withOpacity(1)))
- : (paints..circle(color: colors.secondary))
+ paints..circle(color: colors.secondary)
);
// selected radio in pressed state
@@ -1351,12 +1661,8 @@
expect(
Material.of(tester.element(find.byType(Radio<bool>))),
- paints..circle(color: material3
- ? colors.onSurface.withOpacity(0.12)
- : colors.secondary.withAlpha(0x1F))
- ..circle(color: material3
- ? colors.primary.withOpacity(1)
- : colors.secondary
+ paints..circle(color: colors.secondary.withAlpha(0x1F))
+ ..circle(color: colors.secondary
)
);
@@ -1367,9 +1673,7 @@
expect(
Material.of(tester.element(find.byType(Radio<bool>))),
- material3
- ? (paints..circle(color: colors.primary.withOpacity(0.12))..circle(color: colors.onSurfaceVariant.withOpacity(1)))
- : (paints..circle(color: theme.unselectedWidgetColor.withAlpha(0x1F))..circle(color: theme.unselectedWidgetColor))
+ paints..circle(color: theme.unselectedWidgetColor.withAlpha(0x1F))..circle(color: theme.unselectedWidgetColor)
);
// selected radio in focused state
@@ -1380,9 +1684,7 @@
expect(
Material.of(tester.element(find.byType(Radio<bool>))),
- material3
- ? (paints..circle(color: colors.primary.withOpacity(0.12))..circle(color: colors.primary.withOpacity(1)))
- : (paints..circle(color: theme.focusColor)..circle(color: colors.secondary))
+ paints..circle(color: theme.focusColor)..circle(color: colors.secondary)
);
// unselected radio in focused state
@@ -1393,9 +1695,7 @@
expect(
Material.of(tester.element(find.byType(Radio<bool>))),
- material3
- ? (paints..circle(color: colors.onSurface.withOpacity(0.12))..circle(color: colors.onSurface.withOpacity(1)))
- : (paints..circle(color: theme.focusColor)..circle(color: theme.unselectedWidgetColor))
+ paints..circle(color: theme.focusColor)..circle(color: theme.unselectedWidgetColor)
);
// selected radio in hovered state
@@ -1408,9 +1708,93 @@
expect(
Material.of(tester.element(find.byType(Radio<bool>))),
- material3
- ? (paints..circle(color: colors.primary.withOpacity(0.08))..circle(color: colors.primary.withOpacity(1)))
- : (paints..circle(color: theme.hoverColor)..circle(color: colors.secondary))
+ paints..circle(color: theme.hoverColor)..circle(color: colors.secondary)
+ );
+ });
+
+ testWidgets('Material3 - Radio button default overlay colors in hover/focus/press states', (WidgetTester tester) async {
+ final FocusNode focusNode = FocusNode(debugLabel: 'Radio');
+ tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
+
+ final ThemeData theme = ThemeData(useMaterial3: true);
+ final ColorScheme colors = theme.colorScheme;
+ Widget buildRadio({bool enabled = true, bool focused = false, bool selected = true}) {
+ return MaterialApp(
+ theme: theme,
+ home: Scaffold(
+ body: Radio<bool>(
+ focusNode: focusNode,
+ autofocus: focused,
+ value: true,
+ groupValue: selected,
+ onChanged: enabled ? (_) {} : null,
+ ),
+ ),
+ );
+ }
+
+ // default selected radio
+ await tester.pumpWidget(buildRadio());
+ await tester.pumpAndSettle();
+ expect(
+ Material.of(tester.element(find.byType(Radio<bool>))),
+ paints..circle(color: colors.primary.withOpacity(1))
+ );
+
+ // selected radio in pressed state
+ await tester.pumpWidget(buildRadio());
+ await tester.startGesture(tester.getCenter(find.byType(Radio<bool>)));
+ await tester.pumpAndSettle();
+
+ expect(
+ Material.of(tester.element(find.byType(Radio<bool>))),
+ paints..circle(color: colors.onSurface.withOpacity(0.12))
+ ..circle(color: colors.primary.withOpacity(1))
+ );
+
+ // unselected radio in pressed state
+ await tester.pumpWidget(buildRadio(selected: false));
+ await tester.startGesture(tester.getCenter(find.byType(Radio<bool>)));
+ await tester.pumpAndSettle();
+
+ expect(
+ Material.of(tester.element(find.byType(Radio<bool>))),
+ paints..circle(color: colors.primary.withOpacity(0.12))..circle(color: colors.onSurfaceVariant.withOpacity(1))
+ );
+
+ // selected radio in focused state
+ await tester.pumpWidget(Container()); // reset test
+ await tester.pumpWidget(buildRadio(focused: true));
+ await tester.pumpAndSettle();
+ expect(focusNode.hasPrimaryFocus, isTrue);
+
+ expect(
+ Material.of(tester.element(find.byType(Radio<bool>))),
+ paints..circle(color: colors.primary.withOpacity(0.12))..circle(color: colors.primary.withOpacity(1))
+ );
+
+ // unselected radio in focused state
+ await tester.pumpWidget(Container()); // reset test
+ await tester.pumpWidget(buildRadio(focused: true, selected: false));
+ await tester.pumpAndSettle();
+ expect(focusNode.hasPrimaryFocus, isTrue);
+
+ expect(
+ Material.of(tester.element(find.byType(Radio<bool>))),
+ paints..circle(color: colors.onSurface.withOpacity(0.12))..circle(color: colors.onSurface.withOpacity(1))
+ );
+
+ // selected radio in hovered state
+ await tester.pumpWidget(Container()); // reset test
+ await tester.pumpWidget(buildRadio());
+ final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
+ await gesture.addPointer();
+ await gesture.moveTo(tester.getCenter(find.byType(Radio<bool>)));
+ await tester.pumpAndSettle();
+
+ expect(
+ Material.of(tester.element(find.byType(Radio<bool>))),
+ paints..circle(color: colors.primary.withOpacity(0.08))..circle(color: colors.primary.withOpacity(1))
);
});
@@ -1445,10 +1829,10 @@
}
});
- testWidgets('Radio default overlayColor and fillColor resolves pressed state', (WidgetTester tester) async {
+ testWidgets('Material2 - Radio default overlayColor and fillColor resolves pressed state', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(debugLabel: 'Radio');
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
- final bool material3 = theme.useMaterial3;
+ final ThemeData theme = ThemeData(useMaterial3: false);
Finder findRadio() {
return find.byWidgetPredicate((Widget widget) => widget is Radio<bool>);
@@ -1480,8 +1864,8 @@
expect(getRadioMaterial(tester),
paints
- ..circle(color: material3 ? theme.colorScheme.primary.withOpacity(0.08) : theme.hoverColor)
- ..circle(color: material3 ? theme.colorScheme.primary : theme.colorScheme.secondary)
+ ..circle(color: theme.hoverColor)
+ ..circle(color: theme.colorScheme.secondary)
);
// Highlighted (pressed).
@@ -1490,8 +1874,8 @@
expect(getRadioMaterial(tester),
paints
- ..circle(color: material3 ? theme.colorScheme.onSurface.withOpacity(0.12) : theme.colorScheme.secondary.withAlpha(kRadialReactionAlpha))
- ..circle(color: material3 ? theme.colorScheme.primary : theme.colorScheme.secondary)
+ ..circle(color: theme.colorScheme.secondary.withAlpha(kRadialReactionAlpha))
+ ..circle(color: theme.colorScheme.secondary)
);
// Remove pressed and hovered states
await gesture.up();
@@ -1505,8 +1889,73 @@
expect(getRadioMaterial(tester),
paints
- ..circle(color: material3 ? theme.colorScheme.primary.withOpacity(0.12) : theme.focusColor)
- ..circle(color: material3 ? theme.colorScheme.primary : theme.colorScheme.secondary)
+ ..circle(color: theme.focusColor)
+ ..circle(color: theme.colorScheme.secondary)
+ );
+ });
+
+ testWidgets('Material3 - Radio default overlayColor and fillColor resolves pressed state', (WidgetTester tester) async {
+ final FocusNode focusNode = FocusNode(debugLabel: 'Radio');
+ tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
+ final ThemeData theme = ThemeData(useMaterial3: true);
+
+ Finder findRadio() {
+ return find.byWidgetPredicate((Widget widget) => widget is Radio<bool>);
+ }
+
+ MaterialInkController? getRadioMaterial(WidgetTester tester) {
+ return Material.of(tester.element(findRadio()));
+ }
+ await tester.pumpWidget(MaterialApp(
+ theme: theme,
+ home: Scaffold(
+ body: Radio<bool>(
+ focusNode: focusNode,
+ value: true,
+ groupValue: true,
+ onChanged: (_) { },
+ ),
+ ),
+ ));
+
+ // Hover
+ final Offset center = tester.getCenter(find.byType(Radio<bool>));
+ final TestGesture gesture = await tester.createGesture(
+ kind: PointerDeviceKind.mouse,
+ );
+ await gesture.addPointer();
+ await gesture.moveTo(center);
+ await tester.pumpAndSettle();
+
+ expect(getRadioMaterial(tester),
+ paints
+ ..circle(color: theme.colorScheme.primary.withOpacity(0.08))
+ ..circle(color: theme.colorScheme.primary)
+ );
+
+ // Highlighted (pressed).
+ await gesture.down(center);
+ await tester.pumpAndSettle();
+
+ expect(getRadioMaterial(tester),
+ paints
+ ..circle(color: theme.colorScheme.onSurface.withOpacity(0.12))
+ ..circle(color: theme.colorScheme.primary)
+ );
+ // Remove pressed and hovered states
+ await gesture.up();
+ await tester.pumpAndSettle();
+ await gesture.moveTo(const Offset(0, 50));
+ await tester.pumpAndSettle();
+
+ // Focused.
+ focusNode.requestFocus();
+ await tester.pumpAndSettle();
+
+ expect(getRadioMaterial(tester),
+ paints
+ ..circle(color: theme.colorScheme.primary.withOpacity(0.12))
+ ..circle(color: theme.colorScheme.primary)
);
});
}
diff --git a/packages/flutter/test/material/scaffold_test.dart b/packages/flutter/test/material/scaffold_test.dart
index b204a70..55b38c1 100644
--- a/packages/flutter/test/material/scaffold_test.dart
+++ b/packages/flutter/test/material/scaffold_test.dart
@@ -2801,6 +2801,65 @@
// The scrim should be gone.
expect(findModalBarrier(), findsNothing);
});
+
+ testWidgets("Closing bottom sheet & removing FAB at the same time doesn't throw assertion", (WidgetTester tester) async {
+ final Key bottomSheetKey = UniqueKey();
+ PersistentBottomSheetController<void>? controller;
+ bool show = true;
+
+ await tester.pumpWidget(StatefulBuilder(
+ builder: (_, StateSetter setState) => MaterialApp(
+ home: Scaffold(
+ body: Center(
+ child: Builder(
+ builder: (BuildContext context) => ElevatedButton(
+ onPressed: () {
+ if (controller == null) {
+ controller = showBottomSheet(
+ context: context,
+ builder: (_) => Container(
+ key: bottomSheetKey,
+ height: 200,
+ ),
+ );
+ } else {
+ controller!.close();
+ controller = null;
+ }
+ },
+ child: const Text('BottomSheet'),
+ )),
+ ),
+ floatingActionButton: show
+ ? FloatingActionButton(onPressed: () => setState(() => show = false))
+ : null,
+ ),
+ ),
+ ));
+
+ // Show bottom sheet.
+ await tester.tap(find.byType(ElevatedButton));
+ await tester.pumpAndSettle(const Duration(seconds: 1));
+
+ // Bottom sheet and FAB are visible.
+ expect(find.byType(FloatingActionButton), findsOneWidget);
+ expect(find.byKey(bottomSheetKey), findsOneWidget);
+
+ // Close bottom sheet while removing FAB.
+ await tester.tap(find.byType(FloatingActionButton));
+ await tester.pump(); // start animation
+ await tester.tap(find.byType(ElevatedButton));
+ // Let the animation finish.
+ await tester.pumpAndSettle(const Duration(seconds: 1));
+
+ // Bottom sheet and FAB are gone.
+ expect(find.byType(FloatingActionButton), findsNothing);
+ expect(find.byKey(bottomSheetKey), findsNothing);
+
+ // No exception is thrown.
+ expect(tester.takeException(), isNull);
+ });
+
}
class _GeometryListener extends StatefulWidget {
diff --git a/packages/flutter/test/material/search_anchor_test.dart b/packages/flutter/test/material/search_anchor_test.dart
index 622ddf2..d30cd8e 100644
--- a/packages/flutter/test/material/search_anchor_test.dart
+++ b/packages/flutter/test/material/search_anchor_test.dart
@@ -270,6 +270,26 @@
expect(changeCount, 2);
});
+ testWidgets('SearchBar respects onSubmitted property', (WidgetTester tester) async {
+ String submittedQuery = '';
+ await tester.pumpWidget(
+ MaterialApp(
+ home: Material(
+ child: SearchBar(
+ onSubmitted: (String text) {
+ submittedQuery = text;
+ },
+ ),
+ ),
+ ),
+ );
+
+ await tester.enterText(find.byType(SearchBar), 'query');
+ await tester.testTextInput.receiveAction(TextInputAction.done);
+
+ expect(submittedQuery, equals('query'));
+ });
+
testWidgets('SearchBar respects constraints property', (WidgetTester tester) async {
const BoxConstraints constraints = BoxConstraints(maxWidth: 350.0, minHeight: 80);
await tester.pumpWidget(
@@ -1769,6 +1789,50 @@
expect(searchViewRect.topLeft, equals(const Offset(rootSpacing, rootSpacing)));
});
+ testWidgets('Docked search view with nested navigator does not go off the screen', (WidgetTester tester) async {
+ addTearDown(tester.view.reset);
+ tester.view.physicalSize = const Size(400.0, 400.0);
+ tester.view.devicePixelRatio = 1.0;
+
+ const double rootSpacing = 100.0;
+
+ await tester.pumpWidget(MaterialApp(
+ builder: (BuildContext context, Widget? child) {
+ return Scaffold(
+ body: Padding(
+ padding: const EdgeInsets.all(rootSpacing),
+ child: child,
+ ),
+ );
+ },
+ home: Material(
+ child: Align(
+ alignment: Alignment.bottomRight,
+ child: SearchAnchor(
+ isFullScreen: false,
+ builder: (BuildContext context, SearchController controller) {
+ return IconButton(
+ icon: const Icon(Icons.search),
+ onPressed: () {
+ controller.openView();
+ },
+ );
+ },
+ suggestionsBuilder: (BuildContext context, SearchController controller) {
+ return <Widget>[];
+ },
+ ),
+ ),
+ ),
+ ));
+
+ await tester.tap(find.byIcon(Icons.search));
+ await tester.pumpAndSettle();
+
+ final Rect searchViewRect = tester.getRect(find.descendant(of: findViewContent(), matching: find.byType(SizedBox)).first);
+ expect(searchViewRect.bottomRight, equals(const Offset(300.0, 300.0)));
+ });
+
// Regression tests for https://github.com/flutter/flutter/issues/126623
group('Overall InputDecorationTheme does not impact SearchBar and SearchView', () {
diff --git a/packages/flutter/test/material/search_test.dart b/packages/flutter/test/material/search_test.dart
index 3bf869d..be9a1d6 100644
--- a/packages/flutter/test/material/search_test.dart
+++ b/packages/flutter/test/material/search_test.dart
@@ -589,6 +589,163 @@
expect(tester.testTextInput.setClientArgs!['inputAction'], TextInputAction.done.toString());
});
+ testWidgets('Custom flexibleSpace value', (WidgetTester tester) async {
+ const Widget flexibleSpace = Text('custom flexibleSpace');
+ final _TestSearchDelegate delegate = _TestSearchDelegate(flexibleSpace: flexibleSpace);
+
+ await tester.pumpWidget(TestHomePage(delegate: delegate));
+ await tester.tap(find.byTooltip('Search'));
+ await tester.pumpAndSettle();
+
+ expect(find.byWidget(flexibleSpace), findsOneWidget);
+ });
+
+
+ group('contributes semantics with custom flexibleSpace', () {
+ const Widget flexibleSpace = Text('FlexibleSpace');
+
+ TestSemantics buildExpected({ required String routeName }) {
+ return TestSemantics.root(
+ children: <TestSemantics>[
+ TestSemantics(
+ id: 1,
+ textDirection: TextDirection.ltr,
+ children: <TestSemantics>[
+ TestSemantics(
+ id: 2,
+ children: <TestSemantics>[
+ TestSemantics(
+ id: 3,
+ flags: <SemanticsFlag>[
+ SemanticsFlag.scopesRoute,
+ SemanticsFlag.namesRoute,
+ ],
+ label: routeName,
+ textDirection: TextDirection.ltr,
+ children: <TestSemantics>[
+ TestSemantics(
+ id: 4,
+ children: <TestSemantics>[
+ TestSemantics(
+ id: 6,
+ children: <TestSemantics>[
+ TestSemantics(
+ id: 8,
+ flags: <SemanticsFlag>[
+ SemanticsFlag.hasEnabledState,
+ SemanticsFlag.isButton,
+ SemanticsFlag.isEnabled,
+ SemanticsFlag.isFocusable,
+ ],
+ actions: <SemanticsAction>[SemanticsAction.tap],
+ tooltip: 'Back',
+ textDirection: TextDirection.ltr,
+ ),
+ TestSemantics(
+ id: 9,
+ flags: <SemanticsFlag>[
+ SemanticsFlag.isTextField,
+ SemanticsFlag.isFocused,
+ SemanticsFlag.isHeader,
+ if (debugDefaultTargetPlatformOverride != TargetPlatform.iOS &&
+ debugDefaultTargetPlatformOverride != TargetPlatform.macOS) SemanticsFlag.namesRoute,
+ ],
+ actions: <SemanticsAction>[
+ if (debugDefaultTargetPlatformOverride == TargetPlatform.macOS ||
+ debugDefaultTargetPlatformOverride == TargetPlatform.windows)
+ SemanticsAction.didGainAccessibilityFocus,
+ SemanticsAction.tap,
+ SemanticsAction.setSelection,
+ SemanticsAction.setText,
+ SemanticsAction.paste,
+ ],
+ label: 'Search',
+ textDirection: TextDirection.ltr,
+ textSelection: const TextSelection(baseOffset: 0, extentOffset: 0),
+ ),
+ TestSemantics(
+ id: 10,
+ label: 'Bottom',
+ textDirection: TextDirection.ltr,
+ ),
+ ],
+ ),
+ TestSemantics(
+ id: 7,
+ children: <TestSemantics>[
+ TestSemantics(
+ id: 11,
+ label: 'FlexibleSpace',
+ textDirection: TextDirection.ltr,
+ ),
+ ],
+ ),
+ ],
+ ),
+ TestSemantics(
+ id: 5,
+ flags: <SemanticsFlag>[
+ SemanticsFlag.hasEnabledState,
+ SemanticsFlag.isButton,
+ SemanticsFlag.isEnabled,
+ SemanticsFlag.isFocusable,
+ ],
+ actions: <SemanticsAction>[SemanticsAction.tap],
+ label: 'Suggestions',
+ textDirection: TextDirection.ltr,
+ ),
+ ],
+ ),
+ ],
+ ),
+ ],
+ ),
+ ],
+ );
+ }
+
+ testWidgets('includes routeName on Android', (WidgetTester tester) async {
+ final SemanticsTester semantics = SemanticsTester(tester);
+ final _TestSearchDelegate delegate = _TestSearchDelegate(flexibleSpace: flexibleSpace);
+ await tester.pumpWidget(TestHomePage(
+ delegate: delegate,
+ ));
+
+ await tester.tap(find.byTooltip('Search'));
+ await tester.pumpAndSettle();
+
+ expect(semantics, hasSemantics(
+ buildExpected(routeName: 'Search'),
+ ignoreId: true,
+ ignoreRect: true,
+ ignoreTransform: true,
+ ));
+
+ semantics.dispose();
+ });
+
+ testWidgets('does not include routeName', (WidgetTester tester) async {
+ final SemanticsTester semantics = SemanticsTester(tester);
+ final _TestSearchDelegate delegate = _TestSearchDelegate(flexibleSpace: flexibleSpace);
+ await tester.pumpWidget(TestHomePage(
+ delegate: delegate,
+ ));
+
+ await tester.tap(find.byTooltip('Search'));
+ await tester.pumpAndSettle();
+
+ expect(semantics, hasSemantics(
+ buildExpected(routeName: ''),
+ ignoreId: true,
+ ignoreRect: true,
+ ignoreTransform: true,
+ ));
+
+ semantics.dispose();
+ }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
+ });
+
+
group('contributes semantics', () {
TestSemantics buildExpected({ required String routeName }) {
return TestSemantics.root(
@@ -749,10 +906,10 @@
await tester.tap(find.byTooltip('Search'));
await tester.pumpAndSettle();
- final Material appBarBackground = tester.widget<Material>(find.descendant(
+ final Material appBarBackground = tester.widgetList<Material>(find.descendant(
of: find.byType(AppBar),
matching: find.byType(Material),
- ));
+ )).first;
expect(appBarBackground.color, Colors.white);
final TextField textField = tester.widget<TextField>(find.byType(TextField));
@@ -777,10 +934,10 @@
await tester.tap(find.byTooltip('Search'));
await tester.pumpAndSettle();
- final Material appBarBackground = tester.widget<Material>(find.descendant(
+ final Material appBarBackground = tester.widgetList<Material>(find.descendant(
of: find.byType(AppBar),
matching: find.byType(Material),
- ));
+ )).first;
expect(appBarBackground.color, themeData.primaryColor);
final TextField textField = tester.widget<TextField>(find.byType(TextField));
@@ -789,9 +946,9 @@
});
// Regression test for: https://github.com/flutter/flutter/issues/78144
- testWidgets('`Leading` and `Actions` nullable test', (WidgetTester tester) async {
+ testWidgets('`Leading`, `Actions` and `FlexibleSpace` nullable test', (WidgetTester tester) async {
// The search delegate page is displayed with no issues
- // even with a null return values for [buildLeading] and [buildActions].
+ // even with a null return values for [buildLeading], [buildActions] and [flexibleSpace].
final _TestEmptySearchDelegate delegate = _TestEmptySearchDelegate();
final List<String> selectedResults = <String>[];
@@ -980,6 +1137,7 @@
this.suggestions = 'Suggestions',
this.result = 'Result',
this.actions = const <Widget>[],
+ this.flexibleSpace ,
this.defaultAppBarTheme = false,
super.searchFieldDecorationTheme,
super.searchFieldStyle,
@@ -993,6 +1151,7 @@
final String suggestions;
final String result;
final List<Widget> actions;
+ final Widget? flexibleSpace;
static const Color hintTextColor = Colors.green;
@override
@@ -1049,6 +1208,11 @@
}
@override
+ Widget? buildFlexibleSpace(BuildContext context) {
+ return flexibleSpace;
+ }
+
+ @override
PreferredSizeWidget buildBottom(BuildContext context) {
return const PreferredSize(
preferredSize: Size.fromHeight(56.0),
diff --git a/packages/flutter/test/material/slider_test.dart b/packages/flutter/test/material/slider_test.dart
index cfeee60..a8bf693 100644
--- a/packages/flutter/test/material/slider_test.dart
+++ b/packages/flutter/test/material/slider_test.dart
@@ -1945,6 +1945,7 @@
double value = 0.5;
final ThemeData theme = ThemeData(useMaterial3: true);
final Key sliderKey = UniqueKey();
+ final FocusNode focusNode = FocusNode();
Widget buildApp({bool enabled = true}) {
return MaterialApp(
@@ -1953,8 +1954,9 @@
child: Center(
child: StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
return Slider(
- value: value,
key: sliderKey,
+ value: value,
+ focusNode: focusNode,
onChanged: enabled
? (double newValue) {
setState(() {
@@ -1994,7 +1996,18 @@
await drag.up();
await tester.pumpAndSettle();
- // Slider still has overlay when stopped dragging.
+ // Slider without focus doesn't have overlay when enabled and dragged.
+ expect(focusNode.hasFocus, false);
+ expect(
+ Material.of(tester.element(find.byType(Slider))),
+ isNot(paints..circle(color: theme.colorScheme.primary.withOpacity(0.12))),
+ );
+
+ // Slider has overlay when enabled, dragged and focused.
+ focusNode.requestFocus();
+ await tester.pumpAndSettle();
+
+ expect(focusNode.hasFocus, true);
expect(
Material.of(tester.element(find.byType(Slider))),
paints..circle(color: theme.colorScheme.primary.withOpacity(0.12)),
@@ -2005,6 +2018,7 @@
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
double value = 0.5;
final Key sliderKey = UniqueKey();
+ final FocusNode focusNode = FocusNode();
Widget buildApp({bool enabled = true}) {
return MaterialApp(
@@ -2012,8 +2026,9 @@
child: Center(
child: StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
return Slider(
- value: value,
key: sliderKey,
+ value: value,
+ focusNode: focusNode,
overlayColor: MaterialStateColor.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.dragged)) {
return Colors.lime[500]!;
@@ -2060,10 +2075,11 @@
await drag.up();
await tester.pumpAndSettle();
- // Slider still has overlay when stopped dragging.
+ // Slider without focus doesn't have overlay when enabled and dragged.
+ expect(focusNode.hasFocus, false);
expect(
Material.of(tester.element(find.byType(Slider))),
- paints..circle(color: Colors.lime[500]),
+ isNot(paints..circle(color: Colors.lime[500])),
);
});
@@ -3495,14 +3511,7 @@
await gesture.up();
await tester.pumpAndSettle();
expect(focusNode.hasFocus, true);
- expect(
- Material.of(tester.element(find.byType(Slider))),
- paints..circle(color: overlayColor),
- );
-
- focusNode.unfocus();
- await tester.pumpAndSettle();
- expect(focusNode.hasFocus, false);
+ // Overlay is removed when adjusted with a tap.
expect(
Material.of(tester.element(find.byType(Slider))),
isNot(paints..circle(color: overlayColor)),
@@ -3796,6 +3805,7 @@
double value = 0.5;
final ThemeData theme = ThemeData();
final Key sliderKey = UniqueKey();
+ final FocusNode focusNode = FocusNode();
Widget buildApp({bool enabled = true}) {
return MaterialApp(
@@ -3803,8 +3813,9 @@
child: Center(
child: StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
return Slider(
- value: value,
key: sliderKey,
+ value: value,
+ focusNode: focusNode,
onChanged: enabled
? (double newValue) {
setState(() {
@@ -3844,10 +3855,11 @@
await drag.up();
await tester.pumpAndSettle();
- // Slider still has overlay when stopped dragging.
+ // Slider without focus doesn't have overlay when enabled and dragged.
+ expect(focusNode.hasFocus, false);
expect(
Material.of(tester.element(find.byType(Slider))),
- paints..circle(color: theme.colorScheme.primary.withOpacity(0.12)),
+ isNot(paints..circle(color: theme.colorScheme.primary.withOpacity(0.12))),
);
});
});
diff --git a/packages/flutter/test/material/snack_bar_test.dart b/packages/flutter/test/material/snack_bar_test.dart
index 23497a2..a317534 100644
--- a/packages/flutter/test/material/snack_bar_test.dart
+++ b/packages/flutter/test/material/snack_bar_test.dart
@@ -2155,8 +2155,9 @@
});
testWidgets('SnackBars should be shown above the bottomSheet', (WidgetTester tester) async {
- await tester.pumpWidget(const MaterialApp(
- home: Scaffold(
+ await tester.pumpWidget(MaterialApp(
+ theme: ThemeData(useMaterial3: false),
+ home: const Scaffold(
bottomSheet: SizedBox(
width: 200,
height: 50,
@@ -2238,6 +2239,7 @@
testWidgets('ScaffoldMessenger presents SnackBars to only the root Scaffold when Scaffolds are nested.', (WidgetTester tester) async {
await tester.pumpWidget(MaterialApp(
+ theme: ThemeData(useMaterial3: false),
home: Scaffold(
body: const Scaffold(),
floatingActionButton: FloatingActionButton(onPressed: () {}),
@@ -2439,6 +2441,7 @@
testWidgets('Snackbar by default clips BackdropFilter', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/98205
await tester.pumpWidget(MaterialApp(
+ theme: ThemeData(useMaterial3: false),
home: Scaffold(
body: const Scaffold(),
floatingActionButton: FloatingActionButton(onPressed: () {}),
@@ -2469,8 +2472,9 @@
});
testWidgets('Floating snackbar can display optional icon', (WidgetTester tester) async {
- await tester.pumpWidget(const MaterialApp(
- home: Scaffold(
+ await tester.pumpWidget(MaterialApp(
+ theme: ThemeData(useMaterial3: false),
+ home: const Scaffold(
bottomSheet: SizedBox(
width: 200,
height: 50,
@@ -2500,8 +2504,9 @@
});
testWidgets('Fixed width snackbar can display optional icon', (WidgetTester tester) async {
- await tester.pumpWidget(const MaterialApp(
- home: Scaffold(
+ await tester.pumpWidget(MaterialApp(
+ theme: ThemeData(useMaterial3: false),
+ home: const Scaffold(
bottomSheet: SizedBox(
width: 200,
height: 50,
@@ -2526,8 +2531,9 @@
});
testWidgets('Fixed snackbar can display optional icon without action', (WidgetTester tester) async {
- await tester.pumpWidget(const MaterialApp(
- home: Scaffold(
+ await tester.pumpWidget(MaterialApp(
+ theme: ThemeData(useMaterial3: false),
+ home: const Scaffold(
bottomSheet: SizedBox(
width: 200,
height: 50,
@@ -2554,8 +2560,9 @@
testWidgets(
'Floating width snackbar can display optional icon without action', (WidgetTester tester) async {
- await tester.pumpWidget(const MaterialApp(
- home: Scaffold(
+ await tester.pumpWidget(MaterialApp(
+ theme: ThemeData(useMaterial3: false),
+ home: const Scaffold(
bottomSheet: SizedBox(
width: 200,
height: 50,
@@ -2580,8 +2587,9 @@
});
testWidgets('Floating multi-line snackbar with icon is aligned correctly', (WidgetTester tester) async {
- await tester.pumpWidget(const MaterialApp(
- home: Scaffold(
+ await tester.pumpWidget(MaterialApp(
+ theme: ThemeData(useMaterial3: false),
+ home: const Scaffold(
bottomSheet: SizedBox(
width: 200,
height: 50,
@@ -2607,8 +2615,9 @@
});
testWidgets('Floating multi-line snackbar with icon and actionOverflowThreshold=1 is aligned correctly', (WidgetTester tester) async {
- await tester.pumpWidget(const MaterialApp(
- home: Scaffold(
+ await tester.pumpWidget(MaterialApp(
+ theme: ThemeData(useMaterial3: false),
+ home: const Scaffold(
bottomSheet: SizedBox(
width: 200,
height: 50,
@@ -2627,10 +2636,10 @@
behavior: SnackBarBehavior.floating,
actionOverflowThreshold: 1,
));
- await tester.pumpAndSettle(); // Have the SnackBar fully animate out.
+ await tester.pumpAndSettle(); // Have the SnackBar fully animate in.
await expectLater(find.byType(MaterialApp),
- matchesGoldenFile('snack_bar.goldenTest.multiLineWithIconWithZeroActionOverflowThreshold.png'));
+ matchesGoldenFile('snack_bar.goldenTest.multiLineWithIconWithZeroActionOverflowThreshold.png'));
});
testWidgets(
diff --git a/packages/flutter/test/material/stepper_test.dart b/packages/flutter/test/material/stepper_test.dart
index 3ed4bf5..d85070b 100644
--- a/packages/flutter/test/material/stepper_test.dart
+++ b/packages/flutter/test/material/stepper_test.dart
@@ -972,6 +972,37 @@
}
});
+ testWidgets('ScrollController is passed to the stepper listview', (WidgetTester tester) async {
+ final ScrollController controller = ScrollController();
+ for (final StepperType type in StepperType.values) {
+ await tester.pumpWidget(
+ MaterialApp(
+ home: Material(
+ child: Stepper(
+ controller: controller,
+ type: type,
+ steps: const <Step>[
+ Step(
+ title: Text('Step 1'),
+ content: SizedBox(
+ width: 100.0,
+ height: 100.0,
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ );
+
+ final ListView listView = tester.widget<ListView>(
+ find.descendant(of: find.byType(Stepper),
+ matching: find.byType(ListView),
+ ));
+ expect(listView.controller, controller);
+ }
+ });
+
testWidgets('Stepper horizontal size test', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/pull/77732
Widget buildFrame({ bool isActive = true, Brightness? brightness }) {
diff --git a/packages/flutter/test/material/switch_list_tile_test.dart b/packages/flutter/test/material/switch_list_tile_test.dart
index 818c8b8..e1ffc36 100644
--- a/packages/flutter/test/material/switch_list_tile_test.dart
+++ b/packages/flutter/test/material/switch_list_tile_test.dart
@@ -116,18 +116,70 @@
semantics.dispose();
});
- testWidgets('SwitchListTile has the right colors', (WidgetTester tester) async {
+ testWidgets('Material2 - SwitchListTile has the right colors', (WidgetTester tester) async {
bool value = false;
- final ThemeData theme = ThemeData();
- final bool material3 = theme.useMaterial3;
await tester.pumpWidget(
MediaQuery(
data: const MediaQueryData(padding: EdgeInsets.all(8.0)),
child: Theme(
- data: theme,
+ data: ThemeData(useMaterial3: false),
child: Directionality(
textDirection: TextDirection.ltr,
- child:
+ child: StatefulBuilder(
+ builder: (BuildContext context, StateSetter setState) {
+ return Material(
+ child: SwitchListTile(
+ value: value,
+ onChanged: (bool newValue) {
+ setState(() { value = newValue; });
+ },
+ activeColor: Colors.red[500],
+ activeTrackColor: Colors.green[500],
+ inactiveThumbColor: Colors.yellow[500],
+ inactiveTrackColor: Colors.blue[500],
+ ),
+ );
+ },
+ ),
+ ),
+ ),
+ ),
+ );
+
+ expect(
+ find.byType(Switch),
+ paints
+ ..rrect(color: Colors.blue[500])
+ ..rrect(color: const Color(0x33000000))
+ ..rrect(color: const Color(0x24000000))
+ ..rrect(color: const Color(0x1f000000))
+ ..rrect(color: Colors.yellow[500]),
+ );
+
+ await tester.tap(find.byType(Switch));
+ await tester.pumpAndSettle();
+
+ expect(
+ Material.of(tester.element(find.byType(Switch))),
+ paints
+ ..rrect(color: Colors.green[500])
+ ..rrect(color: const Color(0x33000000))
+ ..rrect(color: const Color(0x24000000))
+ ..rrect(color: const Color(0x1f000000))
+ ..rrect(color: Colors.red[500]),
+ );
+ });
+
+ testWidgets('Material3 - SwitchListTile has the right colors', (WidgetTester tester) async {
+ bool value = false;
+ await tester.pumpWidget(
+ MediaQuery(
+ data: const MediaQueryData(padding: EdgeInsets.all(8.0)),
+ child: Theme(
+ data: ThemeData(useMaterial3: true),
+ child: Directionality(
+ textDirection: TextDirection.ltr,
+ child:
StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return Material(
@@ -151,17 +203,10 @@
expect(
find.byType(Switch),
- material3
- ? (paints
- ..rrect(color: Colors.blue[500])
- ..rrect()
- ..rrect(color: Colors.yellow[500]))
- : (paints
- ..rrect(color: Colors.blue[500])
- ..rrect(color: const Color(0x33000000))
- ..rrect(color: const Color(0x24000000))
- ..rrect(color: const Color(0x1f000000))
- ..rrect(color: Colors.yellow[500])),
+ paints
+ ..rrect(color: Colors.blue[500])
+ ..rrect()
+ ..rrect(color: Colors.yellow[500])
);
await tester.tap(find.byType(Switch));
@@ -169,17 +214,10 @@
expect(
Material.of(tester.element(find.byType(Switch))),
- material3
- ? (paints
- ..rrect(color: Colors.green[500])
- ..rrect()
- ..rrect(color: Colors.red[500]))
- : (paints
- ..rrect(color: Colors.green[500])
- ..rrect(color: const Color(0x33000000))
- ..rrect(color: const Color(0x24000000))
- ..rrect(color: const Color(0x1f000000))
- ..rrect(color: Colors.red[500])),
+ paints
+ ..rrect(color: Colors.green[500])
+ ..rrect()
+ ..rrect(color: Colors.red[500])
);
});
@@ -633,13 +671,11 @@
);
});
- testWidgets('SwitchListTile respects thumbColor in active/enabled states', (WidgetTester tester) async {
+ testWidgets('Material2 - SwitchListTile respects thumbColor in active/enabled states', (WidgetTester tester) async {
const Color activeEnabledThumbColor = Color(0xFF000001);
const Color activeDisabledThumbColor = Color(0xFF000002);
const Color inactiveEnabledThumbColor = Color(0xFF000003);
const Color inactiveDisabledThumbColor = Color(0xFF000004);
- final ThemeData theme = ThemeData();
- final bool material3 = theme.useMaterial3;
Color getThumbColor(Set<MaterialState> states) {
if (states.contains(MaterialState.disabled)) {
@@ -657,8 +693,10 @@
final MaterialStateProperty<Color> thumbColor = MaterialStateColor.resolveWith(getThumbColor);
Widget buildSwitchListTile({required bool enabled, required bool selected}) {
- return wrap(
- child: StatefulBuilder(
+ return MaterialApp(
+ theme: ThemeData(useMaterial3: false),
+ home: Material(
+ child: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return SwitchListTile(
value: selected,
@@ -666,6 +704,7 @@
onChanged: enabled ? (_) { } : null,
);
}),
+ ),
);
}
@@ -673,18 +712,14 @@
await tester.pumpAndSettle();
expect(
Material.of(tester.element(find.byType(Switch))),
- material3
- ? (paints..rrect()..rrect()..rrect(color: inactiveDisabledThumbColor))
- : (paints..rrect()..rrect()..rrect()..rrect()..rrect(color: inactiveDisabledThumbColor)),
+ paints..rrect()..rrect()..rrect()..rrect()..rrect(color: inactiveDisabledThumbColor)
);
await tester.pumpWidget(buildSwitchListTile(enabled: false, selected: true));
await tester.pumpAndSettle();
expect(
Material.of(tester.element(find.byType(Switch))),
- material3
- ? (paints..rrect()..rrect()..rrect(color: activeDisabledThumbColor))
- : (paints..rrect()..rrect()..rrect()..rrect()..rrect(color: activeDisabledThumbColor)),
+ paints..rrect()..rrect()..rrect()..rrect()..rrect(color: activeDisabledThumbColor)
);
await tester.pumpWidget(buildSwitchListTile(enabled: true, selected: false));
@@ -692,9 +727,7 @@
expect(
Material.of(tester.element(find.byType(Switch))),
- material3
- ? (paints..rrect()..rrect()..rrect(color: inactiveEnabledThumbColor))
- : (paints..rrect()..rrect()..rrect()..rrect()..rrect(color: inactiveEnabledThumbColor)),
+ paints..rrect()..rrect()..rrect()..rrect()..rrect(color: inactiveEnabledThumbColor)
);
await tester.pumpWidget(buildSwitchListTile(enabled: true, selected: true));
@@ -702,18 +735,82 @@
expect(
Material.of(tester.element(find.byType(Switch))),
- material3
- ? (paints..rrect()..rrect()..rrect(color: activeEnabledThumbColor))
- : (paints..rrect()..rrect()..rrect()..rrect()..rrect(color: activeEnabledThumbColor)),
+ paints..rrect()..rrect()..rrect()..rrect()..rrect(color: activeEnabledThumbColor)
);
});
- testWidgets('SwitchListTile respects thumbColor in hovered/pressed states', (WidgetTester tester) async {
+ testWidgets('Material3 - SwitchListTile respects thumbColor in active/enabled states', (WidgetTester tester) async {
+ const Color activeEnabledThumbColor = Color(0xFF000001);
+ const Color activeDisabledThumbColor = Color(0xFF000002);
+ const Color inactiveEnabledThumbColor = Color(0xFF000003);
+ const Color inactiveDisabledThumbColor = Color(0xFF000004);
+
+ Color getThumbColor(Set<MaterialState> states) {
+ if (states.contains(MaterialState.disabled)) {
+ if (states.contains(MaterialState.selected)) {
+ return activeDisabledThumbColor;
+ }
+ return inactiveDisabledThumbColor;
+ }
+ if (states.contains(MaterialState.selected)) {
+ return activeEnabledThumbColor;
+ }
+ return inactiveEnabledThumbColor;
+ }
+
+ final MaterialStateProperty<Color> thumbColor = MaterialStateColor.resolveWith(getThumbColor);
+
+ Widget buildSwitchListTile({required bool enabled, required bool selected}) {
+ return MaterialApp(
+ theme: ThemeData(useMaterial3: true),
+ home: Material(
+ child: StatefulBuilder(
+ builder: (BuildContext context, StateSetter setState) {
+ return SwitchListTile(
+ value: selected,
+ thumbColor: thumbColor,
+ onChanged: enabled ? (_) { } : null,
+ );
+ }),
+ ),
+ );
+ }
+
+ await tester.pumpWidget(buildSwitchListTile(enabled: false, selected: false));
+ await tester.pumpAndSettle();
+ expect(
+ Material.of(tester.element(find.byType(Switch))),
+ paints..rrect()..rrect()..rrect(color: inactiveDisabledThumbColor),
+ );
+
+ await tester.pumpWidget(buildSwitchListTile(enabled: false, selected: true));
+ await tester.pumpAndSettle();
+ expect(
+ Material.of(tester.element(find.byType(Switch))),
+ paints..rrect()..rrect()..rrect(color: activeDisabledThumbColor),
+ );
+
+ await tester.pumpWidget(buildSwitchListTile(enabled: true, selected: false));
+ await tester.pumpAndSettle();
+
+ expect(
+ Material.of(tester.element(find.byType(Switch))),
+ paints..rrect()..rrect()..rrect(color: inactiveEnabledThumbColor),
+ );
+
+ await tester.pumpWidget(buildSwitchListTile(enabled: true, selected: true));
+ await tester.pumpAndSettle();
+
+ expect(
+ Material.of(tester.element(find.byType(Switch))),
+ paints..rrect()..rrect()..rrect(color: activeEnabledThumbColor),
+ );
+ });
+
+ testWidgets('Material2 - SwitchListTile respects thumbColor in hovered/pressed states', (WidgetTester tester) async {
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
const Color hoveredThumbColor = Color(0xFF4caf50);
const Color pressedThumbColor = Color(0xFFF44336);
- final ThemeData theme = ThemeData();
- final bool material3 = theme.useMaterial3;
Color getThumbColor(Set<MaterialState> states) {
if (states.contains(MaterialState.pressed)) {
@@ -729,8 +826,8 @@
Widget buildSwitchListTile() {
return MaterialApp(
- theme: theme,
- home: wrap(
+ theme: ThemeData(useMaterial3: false),
+ home: Material(
child: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return SwitchListTile(
@@ -754,9 +851,7 @@
expect(
Material.of(tester.element(find.byType(Switch))),
- material3
- ? (paints..rrect()..rrect()..rrect(color: hoveredThumbColor))
- : (paints..rrect()..rrect()..rrect()..rrect()..rrect(color: hoveredThumbColor)),
+ paints..rrect()..rrect()..rrect()..rrect()..rrect(color: hoveredThumbColor),
);
// On pressed state
@@ -764,9 +859,63 @@
await tester.pumpAndSettle();
expect(
Material.of(tester.element(find.byType(Switch))),
- material3
- ? (paints..rrect()..rrect()..rrect(color: pressedThumbColor))
- : (paints..rrect()..rrect()..rrect()..rrect()..rrect(color: pressedThumbColor)),
+ paints..rrect()..rrect()..rrect()..rrect()..rrect(color: pressedThumbColor),
+ );
+ });
+
+ testWidgets('Material3 - SwitchListTile respects thumbColor in hovered/pressed states', (WidgetTester tester) async {
+ tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
+ const Color hoveredThumbColor = Color(0xFF4caf50);
+ const Color pressedThumbColor = Color(0xFFF44336);
+
+ Color getThumbColor(Set<MaterialState> states) {
+ if (states.contains(MaterialState.pressed)) {
+ return pressedThumbColor;
+ }
+ if (states.contains(MaterialState.hovered)) {
+ return hoveredThumbColor;
+ }
+ return Colors.transparent;
+ }
+
+ final MaterialStateProperty<Color> thumbColor = MaterialStateColor.resolveWith(getThumbColor);
+
+ Widget buildSwitchListTile() {
+ return MaterialApp(
+ theme: ThemeData(useMaterial3: true),
+ home: Material(
+ child: StatefulBuilder(
+ builder: (BuildContext context, StateSetter setState) {
+ return SwitchListTile(
+ value: false,
+ thumbColor: thumbColor,
+ onChanged: (_) { },
+ );
+ }),
+ ),
+ );
+ }
+
+ await tester.pumpWidget(buildSwitchListTile());
+ await tester.pumpAndSettle();
+
+ // Start hovering
+ final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
+ await gesture.moveTo(tester.getCenter(find.byType(Switch)));
+
+ await tester.pumpAndSettle();
+
+ expect(
+ Material.of(tester.element(find.byType(Switch))),
+ paints..rrect()..rrect()..rrect(color: hoveredThumbColor),
+ );
+
+ // On pressed state
+ await tester.press(find.byType(Switch));
+ await tester.pumpAndSettle();
+ expect(
+ Material.of(tester.element(find.byType(Switch))),
+ paints..rrect()..rrect()..rrect(color: pressedThumbColor),
);
});
@@ -961,12 +1110,10 @@
);
});
- testWidgets('SwitchListTile respects materialTapTargetSize', (WidgetTester tester) async {
- final ThemeData theme = ThemeData();
- final bool material3 = theme.useMaterial3;
+ testWidgets('Material2 - SwitchListTile respects materialTapTargetSize', (WidgetTester tester) async {
Widget buildSwitchListTile(MaterialTapTargetSize materialTapTargetSize) {
return MaterialApp(
- theme: theme,
+ theme: ThemeData(useMaterial3: false),
home: Material(
child: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
@@ -983,20 +1130,47 @@
await tester.pumpWidget(buildSwitchListTile(MaterialTapTargetSize.padded));
final Switch switchWidget = tester.widget<Switch>(find.byType(Switch));
expect(switchWidget.materialTapTargetSize, MaterialTapTargetSize.padded);
- expect(tester.getSize(find.byType(Switch)), material3 ? const Size(60.0, 48.0) : const Size(59.0, 48.0));
+ expect(tester.getSize(find.byType(Switch)), const Size(59.0, 48.0));
await tester.pumpWidget(buildSwitchListTile(MaterialTapTargetSize.shrinkWrap));
final Switch switchWidget1 = tester.widget<Switch>(find.byType(Switch));
expect(switchWidget1.materialTapTargetSize, MaterialTapTargetSize.shrinkWrap);
- expect(tester.getSize(find.byType(Switch)), material3 ? const Size(60.0, 40.0) : const Size(59.0, 40.0));
+ expect(tester.getSize(find.byType(Switch)), const Size(59.0, 40.0));
});
- testWidgets('SwitchListTile.adaptive respects applyCupertinoTheme', (WidgetTester tester) async {
- final ThemeData theme = ThemeData();
+ testWidgets('Material3 - SwitchListTile respects materialTapTargetSize', (WidgetTester tester) async {
+ Widget buildSwitchListTile(MaterialTapTargetSize materialTapTargetSize) {
+ return MaterialApp(
+ theme: ThemeData(useMaterial3: true),
+ home: Material(
+ child: StatefulBuilder(
+ builder: (BuildContext context, StateSetter setState) {
+ return SwitchListTile(
+ materialTapTargetSize: materialTapTargetSize,
+ value: false,
+ onChanged: (_) {},
+ );
+ }),
+ ),
+ );
+ }
+
+ await tester.pumpWidget(buildSwitchListTile(MaterialTapTargetSize.padded));
+ final Switch switchWidget = tester.widget<Switch>(find.byType(Switch));
+ expect(switchWidget.materialTapTargetSize, MaterialTapTargetSize.padded);
+ expect(tester.getSize(find.byType(Switch)), const Size(60.0, 48.0));
+
+ await tester.pumpWidget(buildSwitchListTile(MaterialTapTargetSize.shrinkWrap));
+ final Switch switchWidget1 = tester.widget<Switch>(find.byType(Switch));
+ expect(switchWidget1.materialTapTargetSize, MaterialTapTargetSize.shrinkWrap);
+ expect(tester.getSize(find.byType(Switch)), const Size(60.0, 40.0));
+ });
+
+ testWidgets('Material2 - SwitchListTile.adaptive respects applyCupertinoTheme', (WidgetTester tester) async {
Widget buildSwitchListTile(bool applyCupertinoTheme, TargetPlatform platform) {
return MaterialApp(
- theme: theme.copyWith(platform: platform),
- home: wrap(
+ theme: ThemeData(useMaterial3: false, platform: platform),
+ home: Material(
child: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return SwitchListTile.adaptive(
@@ -1015,7 +1189,7 @@
expect(find.byType(CupertinoSwitch), findsOneWidget);
expect(
Material.of(tester.element(find.byType(Switch))),
- paints..rrect(color: theme.useMaterial3 ? const Color(0xFF6750A4) : const Color(0xFF2196F3)),
+ paints..rrect(color: const Color(0xFF2196F3)),
);
await tester.pumpWidget(buildSwitchListTile(false, platform));
@@ -1028,12 +1202,46 @@
}
});
- testWidgets('SwitchListTile respects materialTapTargetSize', (WidgetTester tester) async {
- final ThemeData theme = ThemeData();
- final bool material3 = theme.useMaterial3;
+ testWidgets('Material3 - SwitchListTile.adaptive respects applyCupertinoTheme', (WidgetTester tester) async {
+ Widget buildSwitchListTile(bool applyCupertinoTheme, TargetPlatform platform) {
+ return MaterialApp(
+ theme: ThemeData(useMaterial3: true, platform: platform),
+ home: Material(
+ child: StatefulBuilder(
+ builder: (BuildContext context, StateSetter setState) {
+ return SwitchListTile.adaptive(
+ applyCupertinoTheme: applyCupertinoTheme,
+ value: true,
+ onChanged: (_) {},
+ );
+ }),
+ ),
+ );
+ }
+
+ for (final TargetPlatform platform in <TargetPlatform>[ TargetPlatform.iOS, TargetPlatform.macOS ]) {
+ await tester.pumpWidget(buildSwitchListTile(true, platform));
+ await tester.pumpAndSettle();
+ expect(find.byType(CupertinoSwitch), findsOneWidget);
+ expect(
+ Material.of(tester.element(find.byType(Switch))),
+ paints..rrect(color: const Color(0xFF6750A4)),
+ );
+
+ await tester.pumpWidget(buildSwitchListTile(false, platform));
+ await tester.pumpAndSettle();
+ expect(find.byType(CupertinoSwitch), findsOneWidget);
+ expect(
+ Material.of(tester.element(find.byType(Switch))),
+ paints..rrect(color: const Color(0xFF34C759)),
+ );
+ }
+ });
+
+ testWidgets('Material2 - SwitchListTile respects materialTapTargetSize', (WidgetTester tester) async {
Widget buildSwitchListTile(MaterialTapTargetSize materialTapTargetSize) {
return MaterialApp(
- theme: theme,
+ theme: ThemeData(useMaterial3: false),
home: Material(
child: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
@@ -1050,12 +1258,40 @@
await tester.pumpWidget(buildSwitchListTile(MaterialTapTargetSize.padded));
final Switch switchWidget = tester.widget<Switch>(find.byType(Switch));
expect(switchWidget.materialTapTargetSize, MaterialTapTargetSize.padded);
- expect(tester.getSize(find.byType(Switch)), material3 ? const Size(60.0, 48.0) : const Size(59.0, 48.0));
+ expect(tester.getSize(find.byType(Switch)), const Size(59.0, 48.0));
await tester.pumpWidget(buildSwitchListTile(MaterialTapTargetSize.shrinkWrap));
final Switch switchWidget1 = tester.widget<Switch>(find.byType(Switch));
expect(switchWidget1.materialTapTargetSize, MaterialTapTargetSize.shrinkWrap);
- expect(tester.getSize(find.byType(Switch)), material3 ? const Size(60.0, 40.0) : const Size(59.0, 40.0));
+ expect(tester.getSize(find.byType(Switch)), const Size(59.0, 40.0));
+ });
+
+ testWidgets('Material3 - SwitchListTile respects materialTapTargetSize', (WidgetTester tester) async {
+ Widget buildSwitchListTile(MaterialTapTargetSize materialTapTargetSize) {
+ return MaterialApp(
+ theme: ThemeData(useMaterial3: true),
+ home: Material(
+ child: StatefulBuilder(
+ builder: (BuildContext context, StateSetter setState) {
+ return SwitchListTile(
+ materialTapTargetSize: materialTapTargetSize,
+ value: false,
+ onChanged: (_) {},
+ );
+ }),
+ ),
+ );
+ }
+
+ await tester.pumpWidget(buildSwitchListTile(MaterialTapTargetSize.padded));
+ final Switch switchWidget = tester.widget<Switch>(find.byType(Switch));
+ expect(switchWidget.materialTapTargetSize, MaterialTapTargetSize.padded);
+ expect(tester.getSize(find.byType(Switch)), const Size(60.0, 48.0));
+
+ await tester.pumpWidget(buildSwitchListTile(MaterialTapTargetSize.shrinkWrap));
+ final Switch switchWidget1 = tester.widget<Switch>(find.byType(Switch));
+ expect(switchWidget1.materialTapTargetSize, MaterialTapTargetSize.shrinkWrap);
+ expect(tester.getSize(find.byType(Switch)), const Size(60.0, 40.0));
});
testWidgets('SwitchListTile passes the value of dragStartBehavior to Switch', (WidgetTester tester) async {
diff --git a/packages/flutter/test/material/switch_test.dart b/packages/flutter/test/material/switch_test.dart
index 5ea72bf..f7377f9 100644
--- a/packages/flutter/test/material/switch_test.dart
+++ b/packages/flutter/test/material/switch_test.dart
@@ -106,7 +106,7 @@
expect(tester.getSize(find.byType(Switch)), material3 ? const Size(60.0, 40.0) : const Size(59.0, 40.0));
});
- testWidgets('Switch does not get distorted upon changing constraints with parent - M2', (WidgetTester tester) async {
+ testWidgets('Material2 - Switch does not get distorted upon changing constraints with parent', (WidgetTester tester) async {
const double maxWidth = 300;
const double maxHeight = 100;
@@ -145,7 +145,7 @@
));
await expectLater(
find.byKey(boundaryKey),
- matchesGoldenFile('switch_test.big.on.png'),
+ matchesGoldenFile('m2_switch_test.big.on.png'),
);
await tester.pumpWidget(buildSwitch(
@@ -154,7 +154,59 @@
));
await expectLater(
find.byKey(boundaryKey),
- matchesGoldenFile('switch_test.small.on.png'),
+ matchesGoldenFile('m2_switch_test.small.on.png'),
+ );
+ });
+
+ testWidgets('Material3 - Switch does not get distorted upon changing constraints with parent', (WidgetTester tester) async {
+ const double maxWidth = 300;
+ const double maxHeight = 100;
+
+ const ValueKey<String> boundaryKey = ValueKey<String>('switch container');
+
+ Widget buildSwitch({required double width, required double height}) {
+ return MaterialApp(
+ theme: ThemeData(useMaterial3: true),
+ home: Scaffold(
+ body: Directionality(
+ textDirection: TextDirection.ltr,
+ child: SizedBox(
+ width: maxWidth,
+ height: maxHeight,
+ child: RepaintBoundary(
+ key: boundaryKey,
+ child: SizedBox(
+ width: width,
+ height: height,
+ child: Switch(
+ dragStartBehavior: DragStartBehavior.down,
+ value: true,
+ onChanged: (_) {},
+ ),
+ ),
+ ),
+ ),
+ ),
+ ),
+ );
+ }
+
+ await tester.pumpWidget(buildSwitch(
+ width: maxWidth,
+ height: maxHeight,
+ ));
+ await expectLater(
+ find.byKey(boundaryKey),
+ matchesGoldenFile('m3_switch_test.big.on.png'),
+ );
+
+ await tester.pumpWidget(buildSwitch(
+ width: 20,
+ height: 10,
+ ));
+ await expectLater(
+ find.byKey(boundaryKey),
+ matchesGoldenFile('m3_switch_test.small.on.png'),
);
});
@@ -348,7 +400,7 @@
expect(value, isFalse);
});
- testWidgets('Switch has default colors when enabled - M2', (WidgetTester tester) async {
+ testWidgets('Material2 - Switch has default colors when enabled', (WidgetTester tester) async {
bool value = false;
await tester.pumpWidget(
MaterialApp(
@@ -407,7 +459,72 @@
);
});
- testWidgets('Switch has default colors when disabled - M2', (WidgetTester tester) async {
+ testWidgets('Material3 - Switch has default colors when enabled', (WidgetTester tester) async {
+ final ThemeData theme = ThemeData(useMaterial3: true);
+ final ColorScheme colors = theme.colorScheme;
+ bool value = false;
+ await tester.pumpWidget(
+ MaterialApp(
+ theme: theme,
+ home: Directionality(
+ textDirection: TextDirection.rtl,
+ child: StatefulBuilder(
+ builder: (BuildContext context, StateSetter setState) {
+ return Material(
+ child: Center(
+ child: Switch(
+ dragStartBehavior: DragStartBehavior.down,
+ value: value,
+ onChanged: (bool newValue) {
+ setState(() {
+ value = newValue;
+ });
+ },
+ ),
+ ),
+ );
+ },
+ ),
+ ),
+ ),
+ );
+
+ expect(
+ Material.of(tester.element(find.byType(Switch))),
+ paints
+ ..save()
+ ..rrect(
+ style: PaintingStyle.fill,
+ color: colors.surfaceVariant,
+ rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
+ )
+ ..rrect(
+ style: PaintingStyle.stroke,
+ color: colors.outline,
+ rrect: RRect.fromLTRBR(5.0, 9.0, 55.0, 39.0, const Radius.circular(16.0)),
+ )
+ ..rrect(color: colors.outline), // thumb color
+ reason: 'Inactive enabled switch should match these colors',
+ );
+ await tester.drag(find.byType(Switch), const Offset(-30.0, 0.0));
+ await tester.pump();
+
+ expect(
+ Material.of(tester.element(find.byType(Switch))),
+ paints
+ ..save()
+ ..rrect(
+ style: PaintingStyle.fill,
+ color: colors.primary,
+ rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
+ )
+ ..rrect()
+ ..rrect(color: colors.onPrimary), // thumb color
+ reason: 'Active enabled switch should match these colors',
+ );
+ });
+
+ testWidgets('Material2 - Switch has default colors when disabled', (WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(useMaterial3: false),
@@ -471,10 +588,125 @@
);
});
- testWidgets('Switch default overlayColor resolves hovered/focused state', (WidgetTester tester) async {
+ testWidgets('Material3 - Inactive Switch has default colors when disabled', (WidgetTester tester) async {
+ final ThemeData themeData = ThemeData(useMaterial3: true);
+ final ColorScheme colors = themeData.colorScheme;
+
+ await tester.pumpWidget(MaterialApp(
+ theme: themeData,
+ home: const Directionality(
+ textDirection: TextDirection.rtl,
+ child: Material(
+ child: Center(
+ child: Switch(
+ value: false,
+ onChanged: null,
+ ),
+ ),
+ ),
+ ),
+ ));
+
+ expect(
+ Material.of(tester.element(find.byType(Switch))),
+ paints
+ ..save()
+ ..rrect(
+ style: PaintingStyle.fill,
+ color: colors.surfaceVariant.withOpacity(0.12),
+ rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
+ )
+ ..rrect(
+ style: PaintingStyle.stroke,
+ color: colors.onSurface.withOpacity(0.12),
+ rrect: RRect.fromLTRBR(5.0, 9.0, 55.0, 39.0, const Radius.circular(16.0)),
+ )
+ ..rrect(color: Color.alphaBlend(colors.onSurface.withOpacity(0.38), colors.surface)), // thumb color
+ reason: 'Inactive disabled switch should match these colors',
+ );
+ });
+
+ testWidgets('Material3 - Active Switch has default colors when disabled', (WidgetTester tester) async {
+ final ThemeData themeData = ThemeData(useMaterial3: true);
+ final ColorScheme colors = themeData.colorScheme;
+ await tester.pumpWidget(MaterialApp(
+ theme: themeData,
+ home: const Directionality(
+ textDirection: TextDirection.rtl,
+ child: Material(
+ child: Center(
+ child: Switch(
+ value: true,
+ onChanged: null,
+ ),
+ ),
+ ),
+ ),
+ ));
+
+ expect(
+ Material.of(tester.element(find.byType(Switch))),
+ paints
+ ..save()
+ ..rrect(
+ style: PaintingStyle.fill,
+ color: colors.onSurface.withOpacity(0.12),
+ rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
+ )
+ ..rrect()
+ ..rrect(color: colors.surface), // thumb color
+ reason: 'Active disabled switch should match these colors',
+ );
+ });
+
+ testWidgets('Material2 - Switch default overlayColor resolves hovered/focused state', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(debugLabel: 'Switch');
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
- final bool material3 = theme.useMaterial3;
+ Finder findSwitch() {
+ return find.byWidgetPredicate((Widget widget) => widget is Switch);
+ }
+
+ MaterialInkController? getSwitchMaterial(WidgetTester tester) {
+ return Material.of(tester.element(findSwitch()));
+ }
+ await tester.pumpWidget(MaterialApp(
+ theme: ThemeData(useMaterial3: false),
+ home: Scaffold(
+ body: Switch(
+ focusNode: focusNode,
+ value: true,
+ onChanged: (_) { },
+ ),
+ ),
+ ));
+
+ // Focused.
+ focusNode.requestFocus();
+ await tester.pumpAndSettle();
+
+ expect(getSwitchMaterial(tester),
+ paints
+ ..circle(color: theme.focusColor)
+ );
+
+ // On both hovered and focused, the overlay color should show hovered overlay color.
+ final Offset center = tester.getCenter(find.byType(Switch));
+ final TestGesture gesture = await tester.createGesture(
+ kind: PointerDeviceKind.mouse,
+ );
+ await gesture.addPointer();
+ await gesture.moveTo(center);
+ await tester.pumpAndSettle();
+
+ expect(getSwitchMaterial(tester),
+ paints..circle(color: theme.hoverColor)
+ );
+ });
+
+ testWidgets('Material3 - Switch default overlayColor resolves hovered/focused state', (WidgetTester tester) async {
+ final ThemeData theme = ThemeData(useMaterial3: true);
+ final FocusNode focusNode = FocusNode(debugLabel: 'Switch');
+ tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
Finder findSwitch() {
return find.byWidgetPredicate((Widget widget) => widget is Switch);
@@ -499,8 +731,7 @@
await tester.pumpAndSettle();
expect(getSwitchMaterial(tester),
- paints
- ..circle(color: material3 ? theme.colorScheme.primary.withOpacity(0.12) : theme.focusColor)
+ paints..circle(color: theme.colorScheme.primary.withOpacity(0.12))
);
// On both hovered and focused, the overlay color should show hovered overlay color.
@@ -513,11 +744,11 @@
await tester.pumpAndSettle();
expect(getSwitchMaterial(tester),
- paints..circle(color: material3 ? theme.colorScheme.primary.withOpacity(0.08) : theme.hoverColor)
+ paints..circle(color: theme.colorScheme.primary.withOpacity(0.08))
);
});
- testWidgets('Switch can be set color - M2', (WidgetTester tester) async {
+ testWidgets('Material2 - Switch can be set color', (WidgetTester tester) async {
bool value = false;
await tester.pumpWidget(
MaterialApp(
@@ -578,6 +809,71 @@
);
});
+ testWidgets('Material3 - Switch can be set color', (WidgetTester tester) async {
+ final ThemeData themeData = ThemeData(useMaterial3: true);
+ final ColorScheme colors = themeData.colorScheme;
+
+ bool value = false;
+ await tester.pumpWidget(
+ MaterialApp(
+ theme: themeData,
+ home: Directionality(
+ textDirection: TextDirection.rtl,
+ child: StatefulBuilder(
+ builder: (BuildContext context, StateSetter setState) {
+ return Material(
+ child: Center(
+ child: Switch(
+ dragStartBehavior: DragStartBehavior.down,
+ value: value,
+ onChanged: (bool newValue) {
+ setState(() {
+ value = newValue;
+ });
+ },
+ activeColor: Colors.red[500],
+ activeTrackColor: Colors.green[500],
+ inactiveThumbColor: Colors.yellow[500],
+ inactiveTrackColor: Colors.blue[500],
+ ),
+ ),
+ );
+ },
+ ),
+ ),
+ ),
+ );
+
+ expect(
+ Material.of(tester.element(find.byType(Switch))),
+ paints
+ ..rrect(
+ style: PaintingStyle.fill,
+ color: Colors.blue[500],
+ rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
+ )
+ ..rrect(
+ style: PaintingStyle.stroke,
+ color: colors.outline,
+ )
+ ..rrect(color: Colors.yellow[500]), // thumb color
+ );
+ await tester.drag(find.byType(Switch), const Offset(-30.0, 0.0));
+ await tester.pump();
+
+ expect(
+ Material.of(tester.element(find.byType(Switch))),
+ paints
+ ..rrect(
+ style: PaintingStyle.fill,
+ color: Colors.green[500],
+ rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
+ )
+ ..rrect()
+ ..rrect(color: Colors.red[500]), // thumb color
+ );
+ });
+
testWidgets('Drag ends after animation completes', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/17773
@@ -862,7 +1158,7 @@
}
});
- testWidgets('Switch is focusable and has correct focus color - M2', (WidgetTester tester) async {
+ testWidgets('Material2 - Switch is focusable and has correct focus color', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(debugLabel: 'Switch');
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
bool value = true;
@@ -944,6 +1240,93 @@
);
});
+ testWidgets('Material3 - Switch is focusable and has correct focus color', (WidgetTester tester) async {
+ final ThemeData themeData = ThemeData(useMaterial3: true);
+ final ColorScheme colors = themeData.colorScheme;
+ final FocusNode focusNode = FocusNode(debugLabel: 'Switch');
+ tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
+ bool value = true;
+ Widget buildApp({bool enabled = true}) {
+ return MaterialApp(
+ theme: themeData,
+ home: Material(
+ child: Center(
+ child: StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
+ return Switch(
+ value: value,
+ onChanged: enabled ? (bool newValue) {
+ setState(() {
+ value = newValue;
+ });
+ } : null,
+ focusColor: Colors.orange[500],
+ autofocus: true,
+ focusNode: focusNode,
+ );
+ }),
+ ),
+ ),
+ );
+ }
+ await tester.pumpWidget(buildApp());
+
+ // active, enabled switch
+ await tester.pumpAndSettle();
+ expect(focusNode.hasPrimaryFocus, isTrue);
+ expect(
+ Material.of(tester.element(find.byType(Switch))),
+ paints
+ ..rrect(
+ style: PaintingStyle.fill,
+ color: colors.primary,
+ rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
+ )
+ ..circle(color: Colors.orange[500]),
+ );
+
+ // Check the false value: inactive enabled switch
+ value = false;
+ await tester.pumpWidget(buildApp());
+ await tester.pumpAndSettle();
+ expect(focusNode.hasPrimaryFocus, isTrue);
+ expect(
+ Material.of(tester.element(find.byType(Switch))),
+ paints
+ ..rrect(
+ style: PaintingStyle.fill,
+ color: colors.surfaceVariant,
+ rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
+ )
+ ..rrect(
+ style: PaintingStyle.stroke,
+ color: colors.outline,
+ rrect: RRect.fromLTRBR(5.0, 9.0, 55.0, 39.0, const Radius.circular(16.0)),
+ )
+ ..circle(color: Colors.orange[500])
+ );
+
+ // Check what happens when disabled: inactive disabled switch.
+ value = false;
+ await tester.pumpWidget(buildApp(enabled: false));
+ await tester.pumpAndSettle();
+ expect(focusNode.hasPrimaryFocus, isFalse);
+ expect(
+ Material.of(tester.element(find.byType(Switch))),
+ paints
+ ..rrect(
+ style: PaintingStyle.fill,
+ color: colors.surfaceVariant.withOpacity(0.12),
+ rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
+ )
+ ..rrect(
+ style: PaintingStyle.stroke,
+ color: colors.onSurface.withOpacity(0.12),
+ rrect: RRect.fromLTRBR(5.0, 9.0, 55.0, 39.0, const Radius.circular(16.0)),
+ )
+ ..rrect(color: Color.alphaBlend(colors.onSurface.withOpacity(0.38), colors.surface)),
+ );
+ });
+
testWidgets('Switch with splash radius set', (WidgetTester tester) async {
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
const double splashRadius = 30;
@@ -971,7 +1354,7 @@
);
});
- testWidgets('Switch can be hovered and has correct hover color - M2', (WidgetTester tester) async {
+ testWidgets('Material2 - Switch can be hovered and has correct hover color', (WidgetTester tester) async {
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
bool value = true;
Widget buildApp({bool enabled = true}) {
@@ -1047,6 +1430,78 @@
);
});
+ testWidgets('Material3 - Switch can be hovered and has correct hover color', (WidgetTester tester) async {
+ final ThemeData themeData = ThemeData(useMaterial3: true);
+ final ColorScheme colors = themeData.colorScheme;
+ tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
+ bool value = true;
+ Widget buildApp({bool enabled = true}) {
+ return MaterialApp(
+ theme: themeData,
+ home: Material(
+ child: Center(
+ child: StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
+ return Switch(
+ value: value,
+ onChanged: enabled ? (bool newValue) {
+ setState(() {
+ value = newValue;
+ });
+ } : null,
+ hoverColor: Colors.orange[500],
+ );
+ }),
+ ),
+ ),
+ );
+ }
+
+ // active enabled switch
+ await tester.pumpWidget(buildApp());
+ await tester.pumpAndSettle();
+ expect(
+ Material.of(tester.element(find.byType(Switch))),
+ paints
+ ..rrect(
+ color: colors.primary,
+ rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
+ )
+ ..rrect()
+ ..rrect(color: colors.onPrimary),
+ );
+
+ // Start hovering
+ final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
+ await gesture.addPointer();
+ await gesture.moveTo(tester.getCenter(find.byType(Switch)));
+
+ await tester.pumpWidget(buildApp());
+ await tester.pumpAndSettle();
+ expect(
+ Material.of(tester.element(find.byType(Switch))),
+ paints
+ ..rrect(
+ color: colors.primary,
+ rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
+ )
+ ..circle(color: Colors.orange[500]),
+ );
+
+ // Check what happens for disabled active switch
+ await tester.pumpWidget(buildApp(enabled: false));
+ await tester.pumpAndSettle();
+ expect(
+ Material.of(tester.element(find.byType(Switch))),
+ paints
+ ..rrect(
+ color: colors.onSurface.withOpacity(0.12),
+ rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
+ )
+ ..rrect()
+ ..rrect(color: colors.surface.withOpacity(1.0)),
+ );
+ });
+
testWidgets('Switch can be toggled by keyboard shortcuts', (WidgetTester tester) async {
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
bool value = true;
@@ -1239,7 +1694,7 @@
expect(updatedSwitchState.position.isDismissed, false);
});
- testWidgets('Switch thumb color resolves in active/enabled states - M2', (WidgetTester tester) async {
+ testWidgets('Material2 - Switch thumb color resolves in active/enabled states', (WidgetTester tester) async {
const Color activeEnabledThumbColor = Color(0xFF000001);
const Color activeDisabledThumbColor = Color(0xFF000002);
const Color inactiveEnabledThumbColor = Color(0xFF000003);
@@ -1347,7 +1802,116 @@
);
});
- testWidgets('Switch thumb color resolves in hovered/focused states - M2', (WidgetTester tester) async {
+ testWidgets('Material3 - Switch thumb color resolves in active/enabled states', (WidgetTester tester) async {
+ final ThemeData themeData = ThemeData(useMaterial3: true);
+ final ColorScheme colors = themeData.colorScheme;
+ const Color activeEnabledThumbColor = Color(0xFF000001);
+ const Color activeDisabledThumbColor = Color(0xFF000002);
+ const Color inactiveEnabledThumbColor = Color(0xFF000003);
+ const Color inactiveDisabledThumbColor = Color(0xFF000004);
+
+ Color getThumbColor(Set<MaterialState> states) {
+ if (states.contains(MaterialState.disabled)) {
+ if (states.contains(MaterialState.selected)) {
+ return activeDisabledThumbColor;
+ }
+ return inactiveDisabledThumbColor;
+ }
+ if (states.contains(MaterialState.selected)) {
+ return activeEnabledThumbColor;
+ }
+ return inactiveEnabledThumbColor;
+ }
+
+ final MaterialStateProperty<Color> thumbColor = MaterialStateColor.resolveWith(getThumbColor);
+
+ Widget buildSwitch({required bool enabled, required bool active}) {
+ return Theme(
+ data: themeData,
+ child: Directionality(
+ textDirection: TextDirection.rtl,
+ child: Material(
+ child: Center(
+ child: Switch(
+ thumbColor: thumbColor,
+ value: active,
+ onChanged: enabled ? (_) { } : null,
+ ),
+ ),
+ ),
+ ),
+ );
+ }
+
+ await tester.pumpWidget(buildSwitch(enabled: false, active: false));
+
+ expect(
+ Material.of(tester.element(find.byType(Switch))),
+ paints
+ ..rrect(
+ style: PaintingStyle.fill,
+ color: colors.surfaceVariant.withOpacity(0.12),
+ rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
+ )
+ ..rrect(
+ style: PaintingStyle.stroke,
+ color: colors.onSurface.withOpacity(0.12),
+ rrect: RRect.fromLTRBR(5.0, 9.0, 55.0, 39.0, const Radius.circular(16.0)),
+ )
+ ..rrect(color: inactiveDisabledThumbColor),
+ reason: 'Inactive disabled switch should default track and custom thumb color',
+ );
+
+ await tester.pumpWidget(buildSwitch(enabled: false, active: true));
+ await tester.pumpAndSettle();
+
+ expect(
+ Material.of(tester.element(find.byType(Switch))),
+ paints
+ ..rrect(
+ style: PaintingStyle.fill,
+ color: colors.onSurface.withOpacity(0.12),
+ rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
+ )
+ ..rrect()
+ ..rrect(color: activeDisabledThumbColor),
+ reason: 'Active disabled switch should match these colors',
+ );
+
+ await tester.pumpWidget(buildSwitch(enabled: true, active: false));
+ await tester.pumpAndSettle();
+
+ expect(
+ Material.of(tester.element(find.byType(Switch))),
+ paints
+ ..rrect(
+ style: PaintingStyle.fill,
+ color: colors.surfaceVariant,
+ rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
+ )
+ ..rrect()
+ ..rrect(color: inactiveEnabledThumbColor),
+ reason: 'Inactive enabled switch should match these colors',
+ );
+
+ await tester.pumpWidget(buildSwitch(enabled: true, active: true));
+ await tester.pumpAndSettle();
+
+ expect(
+ Material.of(tester.element(find.byType(Switch))),
+ paints
+ ..rrect(
+ style: PaintingStyle.fill,
+ color: colors.primary,
+ rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
+ )
+ ..rrect()
+ ..rrect(color: activeEnabledThumbColor),
+ reason: 'Active enabled switch should match these colors',
+ );
+ });
+
+ testWidgets('Material2 - Switch thumb color resolves in hovered/focused states', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(debugLabel: 'Switch');
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
const Color hoveredThumbColor = Color(0xFF000001);
@@ -1423,7 +1987,83 @@
);
});
- testWidgets('Track color resolves in active/enabled states - M2', (WidgetTester tester) async {
+ testWidgets('Material3 - Switch thumb color resolves in hovered/focused states', (WidgetTester tester) async {
+ final ThemeData themeData = ThemeData(useMaterial3: true);
+ final ColorScheme colors = themeData.colorScheme;
+ final FocusNode focusNode = FocusNode(debugLabel: 'Switch');
+ tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
+ const Color hoveredThumbColor = Color(0xFF000001);
+ const Color focusedThumbColor = Color(0xFF000002);
+
+ Color getThumbColor(Set<MaterialState> states) {
+ if (states.contains(MaterialState.hovered)) {
+ return hoveredThumbColor;
+ }
+ if (states.contains(MaterialState.focused)) {
+ return focusedThumbColor;
+ }
+ return Colors.transparent;
+ }
+
+ final MaterialStateProperty<Color> thumbColor = MaterialStateColor.resolveWith(getThumbColor);
+
+ Widget buildSwitch() {
+ return MaterialApp(
+ theme: themeData,
+ home: Directionality(
+ textDirection: TextDirection.rtl,
+ child: Material(
+ child: Center(
+ child: Switch(
+ focusNode: focusNode,
+ autofocus: true,
+ value: true,
+ thumbColor: thumbColor,
+ onChanged: (_) { },
+ ),
+ ),
+ ),
+ ),
+ );
+ }
+
+ await tester.pumpWidget(buildSwitch());
+ await tester.pumpAndSettle();
+ expect(focusNode.hasPrimaryFocus, isTrue);
+ expect(
+ Material.of(tester.element(find.byType(Switch))),
+ paints
+ ..rrect(
+ style: PaintingStyle.fill,
+ color: colors.primary,
+ rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
+ )
+ ..circle(color: colors.primary.withOpacity(0.12))
+ ..rrect(color: focusedThumbColor),
+ reason: 'active enabled switch should default track and custom thumb color',
+ );
+
+ // Start hovering
+ final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
+ await gesture.addPointer();
+ await gesture.moveTo(tester.getCenter(find.byType(Switch)));
+ await tester.pumpAndSettle();
+
+ expect(
+ Material.of(tester.element(find.byType(Switch))),
+ paints
+ ..rrect(
+ style: PaintingStyle.fill,
+ color: colors.primary,
+ rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
+ )
+ ..circle(color: colors.primary.withOpacity(0.08))
+ ..rrect(color: hoveredThumbColor),
+ reason: 'active enabled switch should default track and custom thumb color',
+ );
+ });
+
+ testWidgets('Material2 - Track color resolves in active/enabled states', (WidgetTester tester) async {
const Color activeEnabledTrackColor = Color(0xFF000001);
const Color activeDisabledTrackColor = Color(0xFF000002);
const Color inactiveEnabledTrackColor = Color(0xFF000003);
@@ -1512,7 +2152,100 @@
);
});
- testWidgets('Switch track color resolves in hovered/focused states - M2', (WidgetTester tester) async {
+ testWidgets('Material3 - Track color resolves in active/enabled states', (WidgetTester tester) async {
+ final ThemeData themeData = ThemeData(useMaterial3: true);
+ const Color activeEnabledTrackColor = Color(0xFF000001);
+ const Color activeDisabledTrackColor = Color(0xFF000002);
+ const Color inactiveEnabledTrackColor = Color(0xFF000003);
+ const Color inactiveDisabledTrackColor = Color(0xFF000004);
+
+ Color getTrackColor(Set<MaterialState> states) {
+ if (states.contains(MaterialState.disabled)) {
+ if (states.contains(MaterialState.selected)) {
+ return activeDisabledTrackColor;
+ }
+ return inactiveDisabledTrackColor;
+ }
+ if (states.contains(MaterialState.selected)) {
+ return activeEnabledTrackColor;
+ }
+ return inactiveEnabledTrackColor;
+ }
+
+ final MaterialStateProperty<Color> trackColor =
+ MaterialStateColor.resolveWith(getTrackColor);
+
+ Widget buildSwitch({required bool enabled, required bool active}) {
+ return Theme(
+ data: themeData,
+ child: Directionality(
+ textDirection: TextDirection.rtl,
+ child: Material(
+ child: Center(
+ child: Switch(
+ trackColor: trackColor,
+ value: active,
+ onChanged: enabled ? (_) { } : null,
+ ),
+ ),
+ ),
+ ),
+ );
+ }
+
+ await tester.pumpWidget(buildSwitch(enabled: false, active: false));
+
+ expect(
+ Material.of(tester.element(find.byType(Switch))),
+ paints
+ ..rrect(
+ color: inactiveDisabledTrackColor,
+ rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
+ ),
+ reason: 'Inactive disabled switch track should use this value',
+ );
+
+ await tester.pumpWidget(buildSwitch(enabled: false, active: true));
+ await tester.pumpAndSettle();
+
+ expect(
+ Material.of(tester.element(find.byType(Switch))),
+ paints
+ ..rrect(
+ color: activeDisabledTrackColor,
+ rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
+ ),
+ reason: 'Active disabled switch should match these colors',
+ );
+
+ await tester.pumpWidget(buildSwitch(enabled: true, active: false));
+ await tester.pumpAndSettle();
+
+ expect(
+ Material.of(tester.element(find.byType(Switch))),
+ paints
+ ..rrect(
+ color: inactiveEnabledTrackColor,
+ rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
+ ),
+ reason: 'Inactive enabled switch should match these colors',
+ );
+
+ await tester.pumpWidget(buildSwitch(enabled: true, active: true));
+ await tester.pumpAndSettle();
+
+ expect(
+ Material.of(tester.element(find.byType(Switch))),
+ paints
+ ..rrect(
+ color: activeEnabledTrackColor,
+ rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
+ ),
+ reason: 'Active enabled switch should match these colors',
+ );
+ });
+
+ testWidgets('Material2 - Switch track color resolves in hovered/focused states', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(debugLabel: 'Switch');
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
const Color hoveredTrackColor = Color(0xFF000001);
@@ -1581,7 +2314,77 @@
);
});
- testWidgets('Switch thumb color is blended against surface color - M2', (WidgetTester tester) async {
+ testWidgets('Material3 - Switch track color resolves in hovered/focused states', (WidgetTester tester) async {
+ final ThemeData themeData = ThemeData(useMaterial3: true);
+ final FocusNode focusNode = FocusNode(debugLabel: 'Switch');
+ tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
+ const Color hoveredTrackColor = Color(0xFF000001);
+ const Color focusedTrackColor = Color(0xFF000002);
+
+ Color getTrackColor(Set<MaterialState> states) {
+ if (states.contains(MaterialState.hovered)) {
+ return hoveredTrackColor;
+ }
+ if (states.contains(MaterialState.focused)) {
+ return focusedTrackColor;
+ }
+ return Colors.transparent;
+ }
+
+ final MaterialStateProperty<Color> trackColor =
+ MaterialStateColor.resolveWith(getTrackColor);
+
+ Widget buildSwitch() {
+ return Theme(
+ data: themeData,
+ child: Directionality(
+ textDirection: TextDirection.rtl,
+ child: Material(
+ child: Center(
+ child: Switch(
+ focusNode: focusNode,
+ autofocus: true,
+ value: true,
+ trackColor: trackColor,
+ onChanged: (_) { },
+ ),
+ ),
+ ),
+ ),
+ );
+ }
+
+ await tester.pumpWidget(buildSwitch());
+ await tester.pumpAndSettle();
+ expect(focusNode.hasPrimaryFocus, isTrue);
+ expect(
+ Material.of(tester.element(find.byType(Switch))),
+ paints
+ ..rrect(
+ color: focusedTrackColor,
+ rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
+ ),
+ reason: 'Active enabled switch should match these colors',
+ );
+
+ // Start hovering
+ final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
+ await gesture.addPointer();
+ await gesture.moveTo(tester.getCenter(find.byType(Switch)));
+ await tester.pumpAndSettle();
+
+ expect(
+ Material.of(tester.element(find.byType(Switch))),
+ paints
+ ..rrect(
+ color: hoveredTrackColor,
+ rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
+ ),
+ reason: 'Active enabled switch should match these colors',
+ );
+ });
+
+ testWidgets('Material2 - Switch thumb color is blended against surface color', (WidgetTester tester) async {
final Color activeDisabledThumbColor = Colors.blue.withOpacity(.60);
final ThemeData theme = ThemeData.light(useMaterial3: false);
@@ -1632,6 +2435,56 @@
);
});
+ testWidgets('Material3 - Switch thumb color is blended against surface color', (WidgetTester tester) async {
+ final Color activeDisabledThumbColor = Colors.blue.withOpacity(.60);
+ final ThemeData theme = ThemeData(useMaterial3: true);
+ final ColorScheme colors = theme.colorScheme;
+
+ Color getThumbColor(Set<MaterialState> states) {
+ if (states.contains(MaterialState.disabled)) {
+ return activeDisabledThumbColor;
+ }
+ return Colors.black;
+ }
+
+ final MaterialStateProperty<Color> thumbColor =
+ MaterialStateColor.resolveWith(getThumbColor);
+
+ Widget buildSwitch({required bool enabled, required bool active}) {
+ return Directionality(
+ textDirection: TextDirection.rtl,
+ child: Theme(
+ data: theme,
+ child: Material(
+ child: Center(
+ child: Switch(
+ thumbColor: thumbColor,
+ value: active,
+ onChanged: enabled ? (_) { } : null,
+ ),
+ ),
+ ),
+ ),
+ );
+ }
+
+ await tester.pumpWidget(buildSwitch(enabled: false, active: true));
+
+ final Color expectedThumbColor = Color.alphaBlend(activeDisabledThumbColor, theme.colorScheme.surface);
+
+ expect(
+ Material.of(tester.element(find.byType(Switch))),
+ paints
+ ..rrect(
+ color: colors.onSurface.withOpacity(0.12),
+ rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
+ )
+ ..rrect()
+ ..rrect(color: expectedThumbColor),
+ reason: 'Active disabled thumb color should be blended on top of surface color',
+ );
+ });
+
testWidgets('Switch overlay color resolves in active/pressed/focused/hovered states', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(debugLabel: 'Switch');
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
@@ -1983,7 +2836,7 @@
});
});
- group('Switch M3 tests', () {
+ group('Switch M3 only tests', () {
testWidgets('M3 Switch has a 300-millisecond animation in total', (WidgetTester tester) async {
final ThemeData theme = ThemeData(useMaterial3: true);
bool value = false;
@@ -2118,368 +2971,6 @@
expect(state.position.value, greaterThan(1));
});
- testWidgets('Switch has default colors when enabled - M3', (WidgetTester tester) async {
- final ThemeData theme = ThemeData(useMaterial3: true, colorSchemeSeed: const Color(0xff6750a4), brightness: Brightness.light);
- final ColorScheme colors = theme.colorScheme;
- bool value = false;
- await tester.pumpWidget(
- MaterialApp(
- theme: theme,
- home: Directionality(
- textDirection: TextDirection.rtl,
- child: StatefulBuilder(
- builder: (BuildContext context, StateSetter setState) {
- return Material(
- child: Center(
- child: Switch(
- dragStartBehavior: DragStartBehavior.down,
- value: value,
- onChanged: (bool newValue) {
- setState(() {
- value = newValue;
- });
- },
- ),
- ),
- );
- },
- ),
- ),
- ),
- );
-
- expect(
- Material.of(tester.element(find.byType(Switch))),
- paints
- ..save()
- ..rrect(
- style: PaintingStyle.fill,
- color: colors.surfaceVariant,
- rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
- )
- ..rrect(
- style: PaintingStyle.stroke,
- color: colors.outline,
- rrect: RRect.fromLTRBR(5.0, 9.0, 55.0, 39.0, const Radius.circular(16.0)),
- )
- ..rrect(color: colors.outline), // thumb color
- reason: 'Inactive enabled switch should match these colors',
- );
- await tester.drag(find.byType(Switch), const Offset(-30.0, 0.0));
- await tester.pump();
-
- expect(
- Material.of(tester.element(find.byType(Switch))),
- paints
- ..save()
- ..rrect(
- style: PaintingStyle.fill,
- color: colors.primary,
- rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
- )
- ..rrect()
- ..rrect(color: colors.onPrimary), // thumb color
- reason: 'Active enabled switch should match these colors',
- );
- });
-
- testWidgets('Inactive Switch has default colors when disabled - M3', (WidgetTester tester) async {
- final ThemeData themeData = ThemeData(useMaterial3: true, colorSchemeSeed: const Color(0xff6750a4), brightness: Brightness.light);
- final ColorScheme colors = themeData.colorScheme;
-
- await tester.pumpWidget(MaterialApp(
- theme: themeData,
- home: const Directionality(
- textDirection: TextDirection.rtl,
- child: Material(
- child: Center(
- child: Switch(
- value: false,
- onChanged: null,
- ),
- ),
- ),
- ),
- ));
-
- expect(
- Material.of(tester.element(find.byType(Switch))),
- paints
- ..save()
- ..rrect(
- style: PaintingStyle.fill,
- color: colors.surfaceVariant.withOpacity(0.12),
- rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
- )
- ..rrect(
- style: PaintingStyle.stroke,
- color: colors.onSurface.withOpacity(0.12),
- rrect: RRect.fromLTRBR(5.0, 9.0, 55.0, 39.0, const Radius.circular(16.0)),
- )
- ..rrect(color: Color.alphaBlend(colors.onSurface.withOpacity(0.38), colors.surface)), // thumb color
- reason: 'Inactive disabled switch should match these colors',
- );
- });
-
- testWidgets('Active Switch has default colors when disabled - M3', (WidgetTester tester) async {
- final ThemeData themeData = ThemeData(useMaterial3: true,
- colorSchemeSeed: const Color(0xff6750a4),
- brightness: Brightness.light);
- final ColorScheme colors = themeData.colorScheme;
- await tester.pumpWidget(MaterialApp(
- theme: themeData,
- home: const Directionality(
- textDirection: TextDirection.rtl,
- child: Material(
- child: Center(
- child: Switch(
- value: true,
- onChanged: null,
- ),
- ),
- ),
- ),
- ));
-
- expect(
- Material.of(tester.element(find.byType(Switch))),
- paints
- ..save()
- ..rrect(
- style: PaintingStyle.fill,
- color: colors.onSurface.withOpacity(0.12),
- rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
- )
- ..rrect()
- ..rrect(color: colors.surface), // thumb color
- reason: 'Active disabled switch should match these colors',
- );
- });
-
- testWidgets('Switch can be set color - M3', (WidgetTester tester) async {
- final ThemeData themeData = ThemeData(useMaterial3: true, colorSchemeSeed: const Color(0xff6750a4), brightness: Brightness.light);
- final ColorScheme colors = themeData.colorScheme;
-
- bool value = false;
- await tester.pumpWidget(
- MaterialApp(
- theme: themeData,
- home: Directionality(
- textDirection: TextDirection.rtl,
- child: StatefulBuilder(
- builder: (BuildContext context, StateSetter setState) {
- return Material(
- child: Center(
- child: Switch(
- dragStartBehavior: DragStartBehavior.down,
- value: value,
- onChanged: (bool newValue) {
- setState(() {
- value = newValue;
- });
- },
- activeColor: Colors.red[500],
- activeTrackColor: Colors.green[500],
- inactiveThumbColor: Colors.yellow[500],
- inactiveTrackColor: Colors.blue[500],
- ),
- ),
- );
- },
- ),
- ),
- ),
- );
-
- expect(
- Material.of(tester.element(find.byType(Switch))),
- paints
- ..rrect(
- style: PaintingStyle.fill,
- color: Colors.blue[500],
- rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
- )
- ..rrect(
- style: PaintingStyle.stroke,
- color: colors.outline,
- )
- ..rrect(color: Colors.yellow[500]), // thumb color
- );
- await tester.drag(find.byType(Switch), const Offset(-30.0, 0.0));
- await tester.pump();
-
- expect(
- Material.of(tester.element(find.byType(Switch))),
- paints
- ..rrect(
- style: PaintingStyle.fill,
- color: Colors.green[500],
- rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
- )
- ..rrect()
- ..rrect(color: Colors.red[500]), // thumb color
- );
- });
-
- testWidgets('Switch is focusable and has correct focus color - M3', (WidgetTester tester) async {
- final ThemeData themeData = ThemeData(useMaterial3: true, colorSchemeSeed: const Color(0xff6750a4), brightness: Brightness.light);
- final ColorScheme colors = themeData.colorScheme;
- final FocusNode focusNode = FocusNode(debugLabel: 'Switch');
- tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
- bool value = true;
- Widget buildApp({bool enabled = true}) {
- return MaterialApp(
- theme: themeData,
- home: Material(
- child: Center(
- child: StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
- return Switch(
- value: value,
- onChanged: enabled ? (bool newValue) {
- setState(() {
- value = newValue;
- });
- } : null,
- focusColor: Colors.orange[500],
- autofocus: true,
- focusNode: focusNode,
- );
- }),
- ),
- ),
- );
- }
- await tester.pumpWidget(buildApp());
-
- // active, enabled switch
- await tester.pumpAndSettle();
- expect(focusNode.hasPrimaryFocus, isTrue);
- expect(
- Material.of(tester.element(find.byType(Switch))),
- paints
- ..rrect(
- style: PaintingStyle.fill,
- color: colors.primary,
- rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
- )
- ..circle(color: Colors.orange[500]),
- );
-
- // Check the false value: inactive enabled switch
- value = false;
- await tester.pumpWidget(buildApp());
- await tester.pumpAndSettle();
- expect(focusNode.hasPrimaryFocus, isTrue);
- expect(
- Material.of(tester.element(find.byType(Switch))),
- paints
- ..rrect(
- style: PaintingStyle.fill,
- color: colors.surfaceVariant,
- rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
- )
- ..rrect(
- style: PaintingStyle.stroke,
- color: colors.outline,
- rrect: RRect.fromLTRBR(5.0, 9.0, 55.0, 39.0, const Radius.circular(16.0)),
- )
- ..circle(color: Colors.orange[500])
- );
-
- // Check what happens when disabled: inactive disabled switch.
- value = false;
- await tester.pumpWidget(buildApp(enabled: false));
- await tester.pumpAndSettle();
- expect(focusNode.hasPrimaryFocus, isFalse);
- expect(
- Material.of(tester.element(find.byType(Switch))),
- paints
- ..rrect(
- style: PaintingStyle.fill,
- color: colors.surfaceVariant.withOpacity(0.12),
- rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
- )
- ..rrect(
- style: PaintingStyle.stroke,
- color: colors.onSurface.withOpacity(0.12),
- rrect: RRect.fromLTRBR(5.0, 9.0, 55.0, 39.0, const Radius.circular(16.0)),
- )
- ..rrect(color: Color.alphaBlend(colors.onSurface.withOpacity(0.38), colors.surface)),
- );
- });
-
- testWidgets('Switch can be hovered and has correct hover color - M3', (WidgetTester tester) async {
- final ThemeData themeData = ThemeData(useMaterial3: true, colorSchemeSeed: const Color(0xff6750a4), brightness: Brightness.light);
- final ColorScheme colors = themeData.colorScheme;
- tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
- bool value = true;
- Widget buildApp({bool enabled = true}) {
- return MaterialApp(
- theme: themeData,
- home: Material(
- child: Center(
- child: StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
- return Switch(
- value: value,
- onChanged: enabled ? (bool newValue) {
- setState(() {
- value = newValue;
- });
- } : null,
- hoverColor: Colors.orange[500],
- );
- }),
- ),
- ),
- );
- }
-
- // active enabled switch
- await tester.pumpWidget(buildApp());
- await tester.pumpAndSettle();
- expect(
- Material.of(tester.element(find.byType(Switch))),
- paints
- ..rrect(
- color: colors.primary,
- rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
- )
- ..rrect()
- ..rrect(color: colors.onPrimary),
- );
-
- // Start hovering
- final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
- await gesture.addPointer();
- await gesture.moveTo(tester.getCenter(find.byType(Switch)));
-
- await tester.pumpWidget(buildApp());
- await tester.pumpAndSettle();
- expect(
- Material.of(tester.element(find.byType(Switch))),
- paints
- ..rrect(
- color: colors.primary,
- rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
- )
- ..circle(color: Colors.orange[500]),
- );
-
- // Check what happens for disabled active switch
- await tester.pumpWidget(buildApp(enabled: false));
- await tester.pumpAndSettle();
- expect(
- Material.of(tester.element(find.byType(Switch))),
- paints
- ..rrect(
- color: colors.onSurface.withOpacity(0.12),
- rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
- )
- ..rrect()
- ..rrect(color: colors.surface.withOpacity(1.0)),
- );
- });
-
testWidgets('Switch thumb shows correct pressed color - M3', (WidgetTester tester) async {
final ThemeData themeData = ThemeData(useMaterial3: true);
final ColorScheme colors = themeData.colorScheme;
@@ -2563,354 +3054,6 @@
);
}, variant: TargetPlatformVariant.mobile());
- testWidgets('Switch thumb color resolves in active/enabled states - M3', (WidgetTester tester) async {
- final ThemeData themeData = ThemeData(useMaterial3: true, colorSchemeSeed: const Color(0xff6750a4), brightness: Brightness.light);
- final ColorScheme colors = themeData.colorScheme;
- const Color activeEnabledThumbColor = Color(0xFF000001);
- const Color activeDisabledThumbColor = Color(0xFF000002);
- const Color inactiveEnabledThumbColor = Color(0xFF000003);
- const Color inactiveDisabledThumbColor = Color(0xFF000004);
-
- Color getThumbColor(Set<MaterialState> states) {
- if (states.contains(MaterialState.disabled)) {
- if (states.contains(MaterialState.selected)) {
- return activeDisabledThumbColor;
- }
- return inactiveDisabledThumbColor;
- }
- if (states.contains(MaterialState.selected)) {
- return activeEnabledThumbColor;
- }
- return inactiveEnabledThumbColor;
- }
-
- final MaterialStateProperty<Color> thumbColor = MaterialStateColor.resolveWith(getThumbColor);
-
- Widget buildSwitch({required bool enabled, required bool active}) {
- return Theme(
- data: themeData,
- child: Directionality(
- textDirection: TextDirection.rtl,
- child: Material(
- child: Center(
- child: Switch(
- thumbColor: thumbColor,
- value: active,
- onChanged: enabled ? (_) { } : null,
- ),
- ),
- ),
- ),
- );
- }
-
- await tester.pumpWidget(buildSwitch(enabled: false, active: false));
-
- expect(
- Material.of(tester.element(find.byType(Switch))),
- paints
- ..rrect(
- style: PaintingStyle.fill,
- color: colors.surfaceVariant.withOpacity(0.12),
- rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
- )
- ..rrect(
- style: PaintingStyle.stroke,
- color: colors.onSurface.withOpacity(0.12),
- rrect: RRect.fromLTRBR(5.0, 9.0, 55.0, 39.0, const Radius.circular(16.0)),
- )
- ..rrect(color: inactiveDisabledThumbColor),
- reason: 'Inactive disabled switch should default track and custom thumb color',
- );
-
- await tester.pumpWidget(buildSwitch(enabled: false, active: true));
- await tester.pumpAndSettle();
-
- expect(
- Material.of(tester.element(find.byType(Switch))),
- paints
- ..rrect(
- style: PaintingStyle.fill,
- color: colors.onSurface.withOpacity(0.12),
- rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
- )
- ..rrect()
- ..rrect(color: activeDisabledThumbColor),
- reason: 'Active disabled switch should match these colors',
- );
-
- await tester.pumpWidget(buildSwitch(enabled: true, active: false));
- await tester.pumpAndSettle();
-
- expect(
- Material.of(tester.element(find.byType(Switch))),
- paints
- ..rrect(
- style: PaintingStyle.fill,
- color: colors.surfaceVariant,
- rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
- )
- ..rrect()
- ..rrect(color: inactiveEnabledThumbColor),
- reason: 'Inactive enabled switch should match these colors',
- );
-
- await tester.pumpWidget(buildSwitch(enabled: true, active: true));
- await tester.pumpAndSettle();
-
- expect(
- Material.of(tester.element(find.byType(Switch))),
- paints
- ..rrect(
- style: PaintingStyle.fill,
- color: colors.primary,
- rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
- )
- ..rrect()
- ..rrect(color: activeEnabledThumbColor),
- reason: 'Active enabled switch should match these colors',
- );
- });
-
- testWidgets('Switch thumb color resolves in hovered/focused states - M3', (WidgetTester tester) async {
- final ThemeData themeData = ThemeData(useMaterial3: true, colorSchemeSeed: const Color(0xff6750a4), brightness: Brightness.light);
- final ColorScheme colors = themeData.colorScheme;
- final FocusNode focusNode = FocusNode(debugLabel: 'Switch');
- tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
- const Color hoveredThumbColor = Color(0xFF000001);
- const Color focusedThumbColor = Color(0xFF000002);
-
- Color getThumbColor(Set<MaterialState> states) {
- if (states.contains(MaterialState.hovered)) {
- return hoveredThumbColor;
- }
- if (states.contains(MaterialState.focused)) {
- return focusedThumbColor;
- }
- return Colors.transparent;
- }
-
- final MaterialStateProperty<Color> thumbColor = MaterialStateColor.resolveWith(getThumbColor);
-
- Widget buildSwitch() {
- return MaterialApp(
- theme: themeData,
- home: Directionality(
- textDirection: TextDirection.rtl,
- child: Material(
- child: Center(
- child: Switch(
- focusNode: focusNode,
- autofocus: true,
- value: true,
- thumbColor: thumbColor,
- onChanged: (_) { },
- ),
- ),
- ),
- ),
- );
- }
-
- await tester.pumpWidget(buildSwitch());
- await tester.pumpAndSettle();
- expect(focusNode.hasPrimaryFocus, isTrue);
- expect(
- Material.of(tester.element(find.byType(Switch))),
- paints
- ..rrect(
- style: PaintingStyle.fill,
- color: colors.primary,
- rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
- )
- ..circle(color: colors.primary.withOpacity(0.12))
- ..rrect(color: focusedThumbColor),
- reason: 'active enabled switch should default track and custom thumb color',
- );
-
- // Start hovering
- final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
- await gesture.addPointer();
- await gesture.moveTo(tester.getCenter(find.byType(Switch)));
- await tester.pumpAndSettle();
-
- expect(
- Material.of(tester.element(find.byType(Switch))),
- paints
- ..rrect(
- style: PaintingStyle.fill,
- color: colors.primary,
- rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
- )
- ..circle(color: colors.primary.withOpacity(0.08))
- ..rrect(color: hoveredThumbColor),
- reason: 'active enabled switch should default track and custom thumb color',
- );
- });
-
- testWidgets('Track color resolves in active/enabled states - M3', (WidgetTester tester) async {
- final ThemeData themeData = ThemeData(useMaterial3: true, colorSchemeSeed: const Color(0xff6750a4), brightness: Brightness.light);
- const Color activeEnabledTrackColor = Color(0xFF000001);
- const Color activeDisabledTrackColor = Color(0xFF000002);
- const Color inactiveEnabledTrackColor = Color(0xFF000003);
- const Color inactiveDisabledTrackColor = Color(0xFF000004);
-
- Color getTrackColor(Set<MaterialState> states) {
- if (states.contains(MaterialState.disabled)) {
- if (states.contains(MaterialState.selected)) {
- return activeDisabledTrackColor;
- }
- return inactiveDisabledTrackColor;
- }
- if (states.contains(MaterialState.selected)) {
- return activeEnabledTrackColor;
- }
- return inactiveEnabledTrackColor;
- }
-
- final MaterialStateProperty<Color> trackColor =
- MaterialStateColor.resolveWith(getTrackColor);
-
- Widget buildSwitch({required bool enabled, required bool active}) {
- return Theme(
- data: themeData,
- child: Directionality(
- textDirection: TextDirection.rtl,
- child: Material(
- child: Center(
- child: Switch(
- trackColor: trackColor,
- value: active,
- onChanged: enabled ? (_) { } : null,
- ),
- ),
- ),
- ),
- );
- }
-
- await tester.pumpWidget(buildSwitch(enabled: false, active: false));
-
- expect(
- Material.of(tester.element(find.byType(Switch))),
- paints
- ..rrect(
- color: inactiveDisabledTrackColor,
- rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
- ),
- reason: 'Inactive disabled switch track should use this value',
- );
-
- await tester.pumpWidget(buildSwitch(enabled: false, active: true));
- await tester.pumpAndSettle();
-
- expect(
- Material.of(tester.element(find.byType(Switch))),
- paints
- ..rrect(
- color: activeDisabledTrackColor,
- rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
- ),
- reason: 'Active disabled switch should match these colors',
- );
-
- await tester.pumpWidget(buildSwitch(enabled: true, active: false));
- await tester.pumpAndSettle();
-
- expect(
- Material.of(tester.element(find.byType(Switch))),
- paints
- ..rrect(
- color: inactiveEnabledTrackColor,
- rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
- ),
- reason: 'Inactive enabled switch should match these colors',
- );
-
- await tester.pumpWidget(buildSwitch(enabled: true, active: true));
- await tester.pumpAndSettle();
-
- expect(
- Material.of(tester.element(find.byType(Switch))),
- paints
- ..rrect(
- color: activeEnabledTrackColor,
- rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
- ),
- reason: 'Active enabled switch should match these colors',
- );
- });
-
- testWidgets('Switch track color resolves in hovered/focused states - M3', (WidgetTester tester) async {
- final ThemeData themeData = ThemeData(useMaterial3: true, colorSchemeSeed: const Color(0xff6750a4), brightness: Brightness.light);
- final FocusNode focusNode = FocusNode(debugLabel: 'Switch');
- tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
- const Color hoveredTrackColor = Color(0xFF000001);
- const Color focusedTrackColor = Color(0xFF000002);
-
- Color getTrackColor(Set<MaterialState> states) {
- if (states.contains(MaterialState.hovered)) {
- return hoveredTrackColor;
- }
- if (states.contains(MaterialState.focused)) {
- return focusedTrackColor;
- }
- return Colors.transparent;
- }
-
- final MaterialStateProperty<Color> trackColor =
- MaterialStateColor.resolveWith(getTrackColor);
-
- Widget buildSwitch() {
- return Theme(
- data: themeData,
- child: Directionality(
- textDirection: TextDirection.rtl,
- child: Material(
- child: Center(
- child: Switch(
- focusNode: focusNode,
- autofocus: true,
- value: true,
- trackColor: trackColor,
- onChanged: (_) { },
- ),
- ),
- ),
- ),
- );
- }
-
- await tester.pumpWidget(buildSwitch());
- await tester.pumpAndSettle();
- expect(focusNode.hasPrimaryFocus, isTrue);
- expect(
- Material.of(tester.element(find.byType(Switch))),
- paints
- ..rrect(
- color: focusedTrackColor,
- rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
- ),
- reason: 'Active enabled switch should match these colors',
- );
-
- // Start hovering
- final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
- await gesture.addPointer();
- await gesture.moveTo(tester.getCenter(find.byType(Switch)));
- await tester.pumpAndSettle();
-
- expect(
- Material.of(tester.element(find.byType(Switch))),
- paints
- ..rrect(
- color: hoveredTrackColor,
- rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
- ),
- reason: 'Active enabled switch should match these colors',
- );
- });
-
testWidgets('Track outline color resolves in active/enabled states', (WidgetTester tester) async {
const Color activeEnabledTrackOutlineColor = Color(0xFF000001);
const Color activeDisabledTrackOutlineColor = Color(0xFF000002);
@@ -3181,56 +3324,6 @@
);
});
- testWidgets('Switch thumb color is blended against surface color - M3', (WidgetTester tester) async {
- final Color activeDisabledThumbColor = Colors.blue.withOpacity(.60);
- final ThemeData theme = ThemeData.light(useMaterial3: true);
- final ColorScheme colors = theme.colorScheme;
-
- Color getThumbColor(Set<MaterialState> states) {
- if (states.contains(MaterialState.disabled)) {
- return activeDisabledThumbColor;
- }
- return Colors.black;
- }
-
- final MaterialStateProperty<Color> thumbColor =
- MaterialStateColor.resolveWith(getThumbColor);
-
- Widget buildSwitch({required bool enabled, required bool active}) {
- return Directionality(
- textDirection: TextDirection.rtl,
- child: Theme(
- data: theme,
- child: Material(
- child: Center(
- child: Switch(
- thumbColor: thumbColor,
- value: active,
- onChanged: enabled ? (_) { } : null,
- ),
- ),
- ),
- ),
- );
- }
-
- await tester.pumpWidget(buildSwitch(enabled: false, active: true));
-
- final Color expectedThumbColor = Color.alphaBlend(activeDisabledThumbColor, theme.colorScheme.surface);
-
- expect(
- Material.of(tester.element(find.byType(Switch))),
- paints
- ..rrect(
- color: colors.onSurface.withOpacity(0.12),
- rrect: RRect.fromLTRBR(4.0, 8.0, 56.0, 40.0, const Radius.circular(16.0)),
- )
- ..rrect()
- ..rrect(color: expectedThumbColor),
- reason: 'Active disabled thumb color should be blended on top of surface color',
- );
- });
-
testWidgets('Switch can set icon - M3', (WidgetTester tester) async {
final ThemeData themeData = ThemeData(
useMaterial3: true,
diff --git a/packages/flutter/test/material/switch_theme_test.dart b/packages/flutter/test/material/switch_theme_test.dart
index d4d0651..159defb 100644
--- a/packages/flutter/test/material/switch_theme_test.dart
+++ b/packages/flutter/test/material/switch_theme_test.dart
@@ -86,7 +86,7 @@
expect(description[8], 'thumbIcon: MaterialStatePropertyAll(Icon(IconData(U+0007B)))');
});
- testWidgets('Switch is themeable', (WidgetTester tester) async {
+ testWidgets('Material2 - Switch is themeable', (WidgetTester tester) async {
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
const Color defaultThumbColor = Color(0xfffffff0);
@@ -106,6 +106,7 @@
const Icon icon2 = Icon(Icons.close);
final ThemeData themeData = ThemeData(
+ useMaterial3: false,
switchTheme: SwitchThemeData(
thumbColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.selected)) {
@@ -151,7 +152,6 @@
}),
),
);
- final bool material3 = themeData.useMaterial3;
Widget buildSwitch({bool selected = false, bool autofocus = false}) {
return MaterialApp(
theme: themeData,
@@ -171,42 +171,29 @@
await tester.pumpAndSettle();
expect(
_getSwitchMaterial(tester),
- material3
- ? (paints
- ..rrect(color: defaultTrackColor)
- ..rrect(color: defaultTrackOutlineColor, strokeWidth: defaultTrackOutlineWidth)
- ..rrect(color: defaultThumbColor)
- ..paragraph()
- )
- : (paints
+ paints
..rrect(color: defaultTrackColor)
..rrect(color: defaultTrackOutlineColor, strokeWidth: defaultTrackOutlineWidth)
..rrect()
..rrect()
..rrect()
..rrect(color: defaultThumbColor)
- )
);
// Size from MaterialTapTargetSize.shrinkWrap.
- expect(tester.getSize(find.byType(Switch)), material3 ? const Size(60.0, 40.0) : const Size(59.0, 40.0));
+ expect(tester.getSize(find.byType(Switch)), const Size(59.0, 40.0));
// Selected switch.
await tester.pumpWidget(buildSwitch(selected: true));
await tester.pumpAndSettle();
expect(
_getSwitchMaterial(tester),
- material3
- ? (paints
- ..rrect(color: selectedTrackColor)
- ..rrect(color: selectedTrackOutlineColor, strokeWidth: selectedTrackOutlineWidth)
- ..rrect(color: selectedThumbColor)..paragraph())
- : (paints
+ paints
..rrect(color: selectedTrackColor)
..rrect(color: selectedTrackOutlineColor, strokeWidth: selectedTrackOutlineWidth)
..rrect()
..rrect()
..rrect()
- ..rrect(color: selectedThumbColor))
+ ..rrect(color: selectedThumbColor)
);
// Switch with hover.
@@ -222,7 +209,125 @@
expect(_getSwitchMaterial(tester), paints..circle(color: focusOverlayColor, radius: splashRadius));
});
- testWidgets('Switch properties are taken over the theme values', (WidgetTester tester) async {
+ testWidgets('Material3 - Switch is themeable', (WidgetTester tester) async {
+ tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
+
+ const Color defaultThumbColor = Color(0xfffffff0);
+ const Color selectedThumbColor = Color(0xfffffff1);
+ const Color defaultTrackColor = Color(0xfffffff2);
+ const Color selectedTrackColor = Color(0xfffffff3);
+ const Color defaultTrackOutlineColor = Color(0xfffffff4);
+ const Color selectedTrackOutlineColor = Color(0xfffffff5);
+ const double defaultTrackOutlineWidth = 3.0;
+ const double selectedTrackOutlineWidth = 6.0;
+ const MouseCursor mouseCursor = SystemMouseCursors.text;
+ const MaterialTapTargetSize materialTapTargetSize = MaterialTapTargetSize.shrinkWrap;
+ const Color focusOverlayColor = Color(0xfffffff4);
+ const Color hoverOverlayColor = Color(0xfffffff5);
+ const double splashRadius = 1.0;
+ const Icon icon1 = Icon(Icons.check);
+ const Icon icon2 = Icon(Icons.close);
+
+ final ThemeData themeData = ThemeData(
+ useMaterial3: true,
+ switchTheme: SwitchThemeData(
+ thumbColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
+ if (states.contains(MaterialState.selected)) {
+ return selectedThumbColor;
+ }
+ return defaultThumbColor;
+ }),
+ trackColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
+ if (states.contains(MaterialState.selected)) {
+ return selectedTrackColor;
+ }
+ return defaultTrackColor;
+ }),
+ trackOutlineColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
+ if (states.contains(MaterialState.selected)) {
+ return selectedTrackOutlineColor;
+ }
+ return defaultTrackOutlineColor;
+ }),
+ trackOutlineWidth: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
+ if (states.contains(MaterialState.selected)) {
+ return selectedTrackOutlineWidth;
+ }
+ return defaultTrackOutlineWidth;
+ }),
+ mouseCursor: const MaterialStatePropertyAll<MouseCursor>(mouseCursor),
+ materialTapTargetSize: materialTapTargetSize,
+ overlayColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
+ if (states.contains(MaterialState.focused)) {
+ return focusOverlayColor;
+ }
+ if (states.contains(MaterialState.hovered)) {
+ return hoverOverlayColor;
+ }
+ return null;
+ }),
+ splashRadius: splashRadius,
+ thumbIcon: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
+ if (states.contains(MaterialState.selected)) {
+ return icon1;
+ }
+ return icon2;
+ }),
+ ),
+ );
+ Widget buildSwitch({bool selected = false, bool autofocus = false}) {
+ return MaterialApp(
+ theme: themeData,
+ home: Scaffold(
+ body: Switch(
+ dragStartBehavior: DragStartBehavior.down,
+ value: selected,
+ onChanged: (bool value) {},
+ autofocus: autofocus,
+ ),
+ ),
+ );
+ }
+
+ // Switch.
+ await tester.pumpWidget(buildSwitch());
+ await tester.pumpAndSettle();
+ expect(
+ _getSwitchMaterial(tester),
+ paints
+ ..rrect(color: defaultTrackColor)
+ ..rrect(color: defaultTrackOutlineColor, strokeWidth: defaultTrackOutlineWidth)
+ ..rrect(color: defaultThumbColor)
+ ..paragraph()
+ );
+ // Size from MaterialTapTargetSize.shrinkWrap.
+ expect(tester.getSize(find.byType(Switch)), const Size(60.0, 40.0));
+
+ // Selected switch.
+ await tester.pumpWidget(buildSwitch(selected: true));
+ await tester.pumpAndSettle();
+ expect(
+ _getSwitchMaterial(tester),
+ paints
+ ..rrect(color: selectedTrackColor)
+ ..rrect(color: selectedTrackOutlineColor, strokeWidth: selectedTrackOutlineWidth)
+ ..rrect(color: selectedThumbColor)..paragraph()
+ );
+
+ // Switch with hover.
+ await tester.pumpWidget(buildSwitch());
+ await _pointGestureToSwitch(tester);
+ await tester.pumpAndSettle();
+ expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.text);
+ expect(_getSwitchMaterial(tester), paints..circle(color: hoverOverlayColor));
+
+ // Switch with focus.
+ await tester.pumpWidget(buildSwitch(autofocus: true));
+ await tester.pumpAndSettle();
+ expect(_getSwitchMaterial(tester), paints..circle(color: focusOverlayColor, radius: splashRadius));
+ });
+
+ testWidgets('Material2 - Switch properties are taken over the theme values', (WidgetTester tester) async {
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
const Color themeDefaultThumbColor = Color(0xfffffff0);
@@ -254,6 +359,7 @@
const double splashRadius = 2.0;
final ThemeData themeData = ThemeData(
+ useMaterial3: false,
switchTheme: SwitchThemeData(
thumbColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.selected)) {
@@ -299,7 +405,6 @@
}),
),
);
- final bool material3 = themeData.useMaterial3;
Widget buildSwitch({bool selected = false, bool autofocus = false}) {
return MaterialApp(
@@ -354,38 +459,29 @@
await tester.pumpAndSettle();
expect(
_getSwitchMaterial(tester),
- material3
- ? (paints
- ..rrect(color: defaultTrackColor)
- ..rrect(color: defaultOutlineColor, strokeWidth: defaultOutlineWidth)
- ..rrect(color: defaultThumbColor)..paragraph(offset: const Offset(12, 12)))
- : (paints
+ paints
..rrect(color: defaultTrackColor)
..rrect(color: defaultOutlineColor, strokeWidth: defaultOutlineWidth)
..rrect()
..rrect()
..rrect()
- ..rrect(color: defaultThumbColor))
+ ..rrect(color: defaultThumbColor)
);
// Size from MaterialTapTargetSize.shrinkWrap.
- expect(tester.getSize(find.byType(Switch)), material3 ? const Size(60.0, 40.0) : const Size(59.0, 40.0));
+ expect(tester.getSize(find.byType(Switch)), const Size(59.0, 40.0));
// Selected switch.
await tester.pumpWidget(buildSwitch(selected: true));
await tester.pumpAndSettle();
expect(
_getSwitchMaterial(tester),
- material3
- ? (paints
- ..rrect(color: selectedTrackColor)..rrect(color: selectedOutlineColor, strokeWidth: selectedOutlineWidth)
- ..rrect(color: selectedThumbColor))
- : (paints
+ paints
..rrect(color: selectedTrackColor)
..rrect(color: selectedOutlineColor, strokeWidth: selectedOutlineWidth)
..rrect()
..rrect()
..rrect()
- ..rrect(color: selectedThumbColor))
+ ..rrect(color: selectedThumbColor)
);
// Switch with hover.
@@ -401,7 +497,170 @@
expect(_getSwitchMaterial(tester), paints..circle(color: focusColor, radius: splashRadius));
});
- testWidgets('Switch active and inactive properties are taken over the theme values', (WidgetTester tester) async {
+ testWidgets('Material3 - Switch properties are taken over the theme values', (WidgetTester tester) async {
+ tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
+
+ const Color themeDefaultThumbColor = Color(0xfffffff0);
+ const Color themeSelectedThumbColor = Color(0xfffffff1);
+ const Color themeDefaultTrackColor = Color(0xfffffff2);
+ const Color themeSelectedTrackColor = Color(0xfffffff3);
+ const Color themeDefaultOutlineColor = Color(0xfffffff6);
+ const Color themeSelectedOutlineColor = Color(0xfffffff7);
+ const double themeDefaultOutlineWidth = 5.0;
+ const double themeSelectedOutlineWidth = 7.0;
+ const MouseCursor themeMouseCursor = SystemMouseCursors.click;
+ const MaterialTapTargetSize themeMaterialTapTargetSize = MaterialTapTargetSize.padded;
+ const Color themeFocusOverlayColor = Color(0xfffffff4);
+ const Color themeHoverOverlayColor = Color(0xfffffff5);
+ const double themeSplashRadius = 1.0;
+
+ const Color defaultThumbColor = Color(0xffffff0f);
+ const Color selectedThumbColor = Color(0xffffff1f);
+ const Color defaultTrackColor = Color(0xffffff2f);
+ const Color selectedTrackColor = Color(0xffffff3f);
+ const Color defaultOutlineColor = Color(0xffffff6f);
+ const Color selectedOutlineColor = Color(0xffffff7f);
+ const double defaultOutlineWidth = 6.0;
+ const double selectedOutlineWidth = 8.0;
+ const MouseCursor mouseCursor = SystemMouseCursors.text;
+ const MaterialTapTargetSize materialTapTargetSize = MaterialTapTargetSize.shrinkWrap;
+ const Color focusColor = Color(0xffffff4f);
+ const Color hoverColor = Color(0xffffff5f);
+ const double splashRadius = 2.0;
+
+ final ThemeData themeData = ThemeData(
+ useMaterial3: true,
+ switchTheme: SwitchThemeData(
+ thumbColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
+ if (states.contains(MaterialState.selected)) {
+ return themeSelectedThumbColor;
+ }
+ return themeDefaultThumbColor;
+ }),
+ trackColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
+ if (states.contains(MaterialState.selected)) {
+ return themeSelectedTrackColor;
+ }
+ return themeDefaultTrackColor;
+ }),
+ trackOutlineColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
+ if (states.contains(MaterialState.selected)) {
+ return themeSelectedOutlineColor;
+ }
+ return themeDefaultOutlineColor;
+ }),
+ trackOutlineWidth: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
+ if (states.contains(MaterialState.selected)) {
+ return themeSelectedOutlineWidth;
+ }
+ return themeDefaultOutlineWidth;
+ }),
+ mouseCursor: const MaterialStatePropertyAll<MouseCursor>(themeMouseCursor),
+ materialTapTargetSize: themeMaterialTapTargetSize,
+ overlayColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
+ if (states.contains(MaterialState.focused)) {
+ return themeFocusOverlayColor;
+ }
+ if (states.contains(MaterialState.hovered)) {
+ return themeHoverOverlayColor;
+ }
+ return null;
+ }),
+ splashRadius: themeSplashRadius,
+ thumbIcon: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
+ if (states.contains(MaterialState.selected)) {
+ return null;
+ }
+ return null;
+ }),
+ ),
+ );
+
+ Widget buildSwitch({bool selected = false, bool autofocus = false}) {
+ return MaterialApp(
+ theme: themeData,
+ home: Scaffold(
+ body: Switch(
+ value: selected,
+ onChanged: (bool value) {},
+ autofocus: autofocus,
+ thumbColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
+ if (states.contains(MaterialState.selected)) {
+ return selectedThumbColor;
+ }
+ return defaultThumbColor;
+ }),
+ trackColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
+ if (states.contains(MaterialState.selected)) {
+ return selectedTrackColor;
+ }
+ return defaultTrackColor;
+ }),
+ trackOutlineColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
+ if (states.contains(MaterialState.selected)) {
+ return selectedOutlineColor;
+ }
+ return defaultOutlineColor;
+ }),
+ trackOutlineWidth: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
+ if (states.contains(MaterialState.selected)) {
+ return selectedOutlineWidth;
+ }
+ return defaultOutlineWidth;
+ }),
+ mouseCursor: mouseCursor,
+ materialTapTargetSize: materialTapTargetSize,
+ focusColor: focusColor,
+ hoverColor: hoverColor,
+ splashRadius: splashRadius,
+ thumbIcon: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
+ if (states.contains(MaterialState.selected)) {
+ return const Icon(Icons.add);
+ }
+ return const Icon(Icons.access_alarm);
+ }),
+ ),
+ ),
+ );
+ }
+
+ // Switch.
+ await tester.pumpWidget(buildSwitch());
+ await tester.pumpAndSettle();
+ expect(
+ _getSwitchMaterial(tester),
+ paints
+ ..rrect(color: defaultTrackColor)
+ ..rrect(color: defaultOutlineColor, strokeWidth: defaultOutlineWidth)
+ ..rrect(color: defaultThumbColor)..paragraph(offset: const Offset(12, 12))
+ );
+ // Size from MaterialTapTargetSize.shrinkWrap.
+ expect(tester.getSize(find.byType(Switch)), const Size(60.0, 40.0));
+
+ // Selected switch.
+ await tester.pumpWidget(buildSwitch(selected: true));
+ await tester.pumpAndSettle();
+ expect(
+ _getSwitchMaterial(tester),
+ paints
+ ..rrect(color: selectedTrackColor)..rrect(color: selectedOutlineColor, strokeWidth: selectedOutlineWidth)
+ ..rrect(color: selectedThumbColor)
+ );
+
+ // Switch with hover.
+ await tester.pumpWidget(buildSwitch());
+ await _pointGestureToSwitch(tester);
+ await tester.pumpAndSettle();
+ expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.text);
+ expect(_getSwitchMaterial(tester), paints..circle(color: hoverColor));
+
+ // Switch with focus.
+ await tester.pumpWidget(buildSwitch(autofocus: true));
+ await tester.pumpAndSettle();
+ expect(_getSwitchMaterial(tester), paints..circle(color: focusColor, radius: splashRadius));
+ });
+
+ testWidgets('Material2 - Switch active and inactive properties are taken over the theme values', (WidgetTester tester) async {
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
const Color themeDefaultThumbColor = Color(0xfffffff0);
@@ -415,6 +674,7 @@
const Color selectedTrackColor = Color(0xffffff3f);
final ThemeData themeData = ThemeData(
+ useMaterial3: false,
switchTheme: SwitchThemeData(
thumbColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.selected)) {
@@ -430,7 +690,6 @@
}),
),
);
- final bool material3 = themeData.useMaterial3;
Widget buildSwitch({bool selected = false, bool autofocus = false}) {
return MaterialApp(
@@ -454,17 +713,12 @@
await tester.pumpAndSettle();
expect(
_getSwitchMaterial(tester),
- material3
- ? (paints
- ..rrect(color: defaultTrackColor)
- ..rrect(color: themeData.colorScheme.outline)
- ..rrect(color: defaultThumbColor))
- : (paints
- ..rrect(color: defaultTrackColor)
- ..rrect()
- ..rrect()
- ..rrect()
- ..rrect(color: defaultThumbColor))
+ paints
+ ..rrect(color: defaultTrackColor)
+ ..rrect()
+ ..rrect()
+ ..rrect()
+ ..rrect(color: defaultThumbColor)
);
// Selected switch.
@@ -472,21 +726,87 @@
await tester.pumpAndSettle();
expect(
_getSwitchMaterial(tester),
- material3
- ? (paints
- ..rrect(color: selectedTrackColor)
- ..rrect()
- ..rrect(color: selectedThumbColor))
- : (paints
+ paints
..rrect(color: selectedTrackColor)
..rrect()
..rrect()
..rrect()
- ..rrect(color: selectedThumbColor))
+ ..rrect(color: selectedThumbColor)
);
});
- testWidgets('Switch theme overlay color resolves in active/pressed states', (WidgetTester tester) async {
+ testWidgets('Material3 - Switch active and inactive properties are taken over the theme values', (WidgetTester tester) async {
+ tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
+
+ const Color themeDefaultThumbColor = Color(0xfffffff0);
+ const Color themeSelectedThumbColor = Color(0xfffffff1);
+ const Color themeDefaultTrackColor = Color(0xfffffff2);
+ const Color themeSelectedTrackColor = Color(0xfffffff3);
+
+ const Color defaultThumbColor = Color(0xffffff0f);
+ const Color selectedThumbColor = Color(0xffffff1f);
+ const Color defaultTrackColor = Color(0xffffff2f);
+ const Color selectedTrackColor = Color(0xffffff3f);
+
+ final ThemeData themeData = ThemeData(
+ useMaterial3: true,
+ switchTheme: SwitchThemeData(
+ thumbColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
+ if (states.contains(MaterialState.selected)) {
+ return themeSelectedThumbColor;
+ }
+ return themeDefaultThumbColor;
+ }),
+ trackColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
+ if (states.contains(MaterialState.selected)) {
+ return themeSelectedTrackColor;
+ }
+ return themeDefaultTrackColor;
+ }),
+ ),
+ );
+
+ Widget buildSwitch({bool selected = false, bool autofocus = false}) {
+ return MaterialApp(
+ theme: themeData,
+ home: Scaffold(
+ body: Switch(
+ value: selected,
+ onChanged: (bool value) {},
+ autofocus: autofocus,
+ activeColor: selectedThumbColor,
+ inactiveThumbColor: defaultThumbColor,
+ activeTrackColor: selectedTrackColor,
+ inactiveTrackColor: defaultTrackColor,
+ ),
+ ),
+ );
+ }
+
+ // Unselected switch.
+ await tester.pumpWidget(buildSwitch());
+ await tester.pumpAndSettle();
+ expect(
+ _getSwitchMaterial(tester),
+ paints
+ ..rrect(color: defaultTrackColor)
+ ..rrect(color: themeData.colorScheme.outline)
+ ..rrect(color: defaultThumbColor)
+ );
+
+ // Selected switch.
+ await tester.pumpWidget(buildSwitch(selected: true));
+ await tester.pumpAndSettle();
+ expect(
+ _getSwitchMaterial(tester),
+ paints
+ ..rrect(color: selectedTrackColor)
+ ..rrect()
+ ..rrect(color: selectedThumbColor)
+ );
+ });
+
+ testWidgets('Material2 - Switch theme overlay color resolves in active/pressed states', (WidgetTester tester) async {
const Color activePressedOverlayColor = Color(0xFF000001);
const Color inactivePressedOverlayColor = Color(0xFF000002);
@@ -501,12 +821,12 @@
}
const double splashRadius = 24.0;
final ThemeData themeData = ThemeData(
+ useMaterial3: false,
switchTheme: SwitchThemeData(
overlayColor: MaterialStateProperty.resolveWith(getOverlayColor),
splashRadius: splashRadius,
),
);
- final bool material3 = themeData.useMaterial3;
Widget buildSwitch({required bool active}) {
return MaterialApp(
@@ -526,20 +846,12 @@
expect(
_getSwitchMaterial(tester),
- material3
- ? ((paints
- ..rrect()
- ..rrect())
- ..circle(
- color: inactivePressedOverlayColor,
- radius: splashRadius,
- ))
- : (paints
+ paints
..rrect()
..circle(
color: inactivePressedOverlayColor,
radius: splashRadius,
- )),
+ ),
reason: 'Inactive pressed Switch should have overlay color: $inactivePressedOverlayColor',
);
@@ -559,7 +871,73 @@
);
});
- testWidgets('Local SwitchTheme can override global SwitchTheme', (WidgetTester tester) async {
+ testWidgets('Material3 - Switch theme overlay color resolves in active/pressed states', (WidgetTester tester) async {
+ const Color activePressedOverlayColor = Color(0xFF000001);
+ const Color inactivePressedOverlayColor = Color(0xFF000002);
+
+ Color? getOverlayColor(Set<MaterialState> states) {
+ if (states.contains(MaterialState.pressed)) {
+ if (states.contains(MaterialState.selected)) {
+ return activePressedOverlayColor;
+ }
+ return inactivePressedOverlayColor;
+ }
+ return null;
+ }
+ const double splashRadius = 24.0;
+ final ThemeData themeData = ThemeData(
+ useMaterial3: true,
+ switchTheme: SwitchThemeData(
+ overlayColor: MaterialStateProperty.resolveWith(getOverlayColor),
+ splashRadius: splashRadius,
+ ),
+ );
+
+ Widget buildSwitch({required bool active}) {
+ return MaterialApp(
+ theme: themeData,
+ home: Scaffold(
+ body: Switch(
+ value: active,
+ onChanged: (_) { },
+ ),
+ ),
+ );
+ }
+
+ await tester.pumpWidget(buildSwitch(active: false));
+ await tester.press(find.byType(Switch));
+ await tester.pumpAndSettle();
+
+ expect(
+ _getSwitchMaterial(tester),
+ (paints
+ ..rrect()
+ ..rrect())
+ ..circle(
+ color: inactivePressedOverlayColor,
+ radius: splashRadius,
+ ),
+ reason: 'Inactive pressed Switch should have overlay color: $inactivePressedOverlayColor',
+ );
+
+ await tester.pumpWidget(buildSwitch(active: true));
+ await tester.press(find.byType(Switch));
+ await tester.pumpAndSettle();
+
+ expect(
+ _getSwitchMaterial(tester),
+ paints
+ ..rrect()
+ ..circle(
+ color: activePressedOverlayColor,
+ radius: splashRadius,
+ ),
+ reason: 'Active pressed Switch should have overlay color: $activePressedOverlayColor',
+ );
+ });
+
+ testWidgets('Material2 - Local SwitchTheme can override global SwitchTheme', (WidgetTester tester) async {
const Color globalThemeThumbColor = Color(0xfffffff1);
const Color globalThemeTrackColor = Color(0xfffffff2);
const Color globalThemeOutlineColor = Color(0xfffffff3);
@@ -570,6 +948,7 @@
const double localThemeOutlineWidth = 4.0;
final ThemeData themeData = ThemeData(
+ useMaterial3: false,
switchTheme: const SwitchThemeData(
thumbColor: MaterialStatePropertyAll<Color>(globalThemeThumbColor),
trackColor: MaterialStatePropertyAll<Color>(globalThemeTrackColor),
@@ -577,7 +956,6 @@
trackOutlineWidth: MaterialStatePropertyAll<double>(globalThemeOutlineWidth),
),
);
- final bool material3 = themeData.useMaterial3;
Widget buildSwitch({bool selected = false, bool autofocus = false}) {
return MaterialApp(
theme: themeData,
@@ -603,18 +981,64 @@
await tester.pumpAndSettle();
expect(
_getSwitchMaterial(tester),
- material3
- ? (paints
- ..rrect(color: localThemeTrackColor)
- ..rrect(color: localThemeOutlineColor, strokeWidth: localThemeOutlineWidth)
- ..rrect(color: localThemeThumbColor))
- : (paints
+ paints
..rrect(color: localThemeTrackColor)
..rrect(color: localThemeOutlineColor, strokeWidth: localThemeOutlineWidth)
..rrect()
..rrect()
..rrect()
- ..rrect(color: localThemeThumbColor))
+ ..rrect(color: localThemeThumbColor)
+ );
+ });
+
+ testWidgets('Material3 - Local SwitchTheme can override global SwitchTheme', (WidgetTester tester) async {
+ const Color globalThemeThumbColor = Color(0xfffffff1);
+ const Color globalThemeTrackColor = Color(0xfffffff2);
+ const Color globalThemeOutlineColor = Color(0xfffffff3);
+ const double globalThemeOutlineWidth = 6.0;
+ const Color localThemeThumbColor = Color(0xffff0000);
+ const Color localThemeTrackColor = Color(0xffff0000);
+ const Color localThemeOutlineColor = Color(0xffff0000);
+ const double localThemeOutlineWidth = 4.0;
+
+ final ThemeData themeData = ThemeData(
+ useMaterial3: true,
+ switchTheme: const SwitchThemeData(
+ thumbColor: MaterialStatePropertyAll<Color>(globalThemeThumbColor),
+ trackColor: MaterialStatePropertyAll<Color>(globalThemeTrackColor),
+ trackOutlineColor: MaterialStatePropertyAll<Color>(globalThemeOutlineColor),
+ trackOutlineWidth: MaterialStatePropertyAll<double>(globalThemeOutlineWidth),
+ ),
+ );
+ Widget buildSwitch({bool selected = false, bool autofocus = false}) {
+ return MaterialApp(
+ theme: themeData,
+ home: Scaffold(
+ body: SwitchTheme(
+ data: const SwitchThemeData(
+ thumbColor: MaterialStatePropertyAll<Color>(localThemeThumbColor),
+ trackColor: MaterialStatePropertyAll<Color>(localThemeTrackColor),
+ trackOutlineColor: MaterialStatePropertyAll<Color>(localThemeOutlineColor),
+ trackOutlineWidth: MaterialStatePropertyAll<double>(localThemeOutlineWidth)
+ ),
+ child: Switch(
+ value: selected,
+ onChanged: (bool value) {},
+ autofocus: autofocus,
+ ),
+ ),
+ ),
+ );
+ }
+
+ await tester.pumpWidget(buildSwitch(selected: true));
+ await tester.pumpAndSettle();
+ expect(
+ _getSwitchMaterial(tester),
+ paints
+ ..rrect(color: localThemeTrackColor)
+ ..rrect(color: localThemeOutlineColor, strokeWidth: localThemeOutlineWidth)
+ ..rrect(color: localThemeThumbColor)
);
});
}
diff --git a/packages/flutter/test/material/text_field_test.dart b/packages/flutter/test/material/text_field_test.dart
index 687fda4..b7a226e 100644
--- a/packages/flutter/test/material/text_field_test.dart
+++ b/packages/flutter/test/material/text_field_test.dart
@@ -26,6 +26,7 @@
import '../widgets/clipboard_utils.dart';
import '../widgets/editable_text_utils.dart';
+import '../widgets/live_text_utils.dart';
import '../widgets/semantics_tester.dart';
import 'feedback_tester.dart';
@@ -203,6 +204,47 @@
);
}
+ testWidgets(
+ 'Live Text button shows and hides correctly when LiveTextStatus changes',
+ (WidgetTester tester) async {
+ final LiveTextInputTester liveTextInputTester = LiveTextInputTester();
+ addTearDown(liveTextInputTester.dispose);
+ final TextEditingController controller = TextEditingController(text: '');
+ const Key key = ValueKey<String>('TextField');
+ final FocusNode focusNode = FocusNode();
+ final Widget app = MaterialApp(
+ theme: ThemeData(platform: TargetPlatform.iOS),
+ home: Scaffold(
+ body: Center(
+ child: TextField(
+ key: key,
+ controller: controller,
+ focusNode: focusNode,
+ ),
+ ),
+ ),
+ );
+
+ liveTextInputTester.mockLiveTextInputEnabled = true;
+ await tester.pumpWidget(app);
+ focusNode.requestFocus();
+ await tester.pumpAndSettle();
+
+ final Finder textFinder = find.byType(EditableText);
+ await tester.longPress(textFinder);
+ await tester.pumpAndSettle();
+ expect(
+ findLiveTextButton(),
+ kIsWeb ? findsNothing : findsOneWidget,
+ );
+
+ liveTextInputTester.mockLiveTextInputEnabled = false;
+ await tester.longPress(textFinder);
+ await tester.pumpAndSettle();
+ expect(findLiveTextButton(), findsNothing);
+ },
+ );
+
testWidgets('text field selection toolbar should hide when the user starts typing', (WidgetTester tester) async {
await tester.pumpWidget(
const MaterialApp(
@@ -918,13 +960,16 @@
});
testWidgets('Material cursor golden', (WidgetTester tester) async {
- final Widget widget = overlay(
- child: const RepaintBoundary(
- key: ValueKey<int>(1),
- child: TextField(
- cursorColor: Colors.blue,
- cursorWidth: 15,
- cursorRadius: Radius.circular(3.0),
+ final Widget widget = Theme(
+ data: ThemeData(useMaterial3: false),
+ child: overlay(
+ child: const RepaintBoundary(
+ key: ValueKey<int>(1),
+ child: TextField(
+ cursorColor: Colors.blue,
+ cursorWidth: 15,
+ cursorRadius: Radius.circular(3.0),
+ ),
),
),
);
@@ -1095,6 +1140,7 @@
);
await tester.pumpWidget(
MaterialApp(
+ theme: ThemeData(useMaterial3: false),
home: Material(
child: Center(
child: RepaintBoundary(
@@ -1143,6 +1189,7 @@
);
await tester.pumpWidget(
MaterialApp(
+ theme: ThemeData(useMaterial3: false),
home: Material(
child: Center(
child: RepaintBoundary(
@@ -2142,6 +2189,52 @@
variant: TargetPlatformVariant.mobile(),
);
+ testWidgets('Can select text with a mouse when wrapped in a GestureDetector with tap/double tap callbacks', (WidgetTester tester) async {
+ // This is a regression test for https://github.com/flutter/flutter/issues/129161.
+ final TextEditingController controller = TextEditingController();
+
+ await tester.pumpWidget(
+ MaterialApp(
+ home: Material(
+ child: GestureDetector(
+ onTap: () {},
+ onDoubleTap: () {},
+ child: TextField(
+ dragStartBehavior: DragStartBehavior.down,
+ controller: controller,
+ ),
+ ),
+ ),
+ ),
+ );
+
+ const String testValue = 'abc def ghi';
+ await tester.enterText(find.byType(TextField), testValue);
+ await skipPastScrollingAnimation(tester);
+
+ final Offset ePos = textOffsetToPosition(tester, testValue.indexOf('e'));
+ final Offset gPos = textOffsetToPosition(tester, testValue.indexOf('g'));
+
+ final TestGesture gesture = await tester.startGesture(ePos, kind: PointerDeviceKind.mouse);
+ await tester.pump();
+ await gesture.up();
+ // This is to allow the GestureArena to decide a winner between TapGestureRecognizer,
+ // DoubleTapGestureRecognizer, and BaseTapAndDragGestureRecognizer.
+ await tester.pumpAndSettle(kDoubleTapTimeout);
+ expect(controller.selection.isCollapsed, true);
+ expect(controller.selection.baseOffset, testValue.indexOf('e'));
+
+ await gesture.down(ePos);
+ await tester.pump();
+ await gesture.moveTo(gPos);
+ await tester.pump();
+ await gesture.up();
+ await tester.pumpAndSettle();
+
+ expect(controller.selection.baseOffset, testValue.indexOf('e'));
+ expect(controller.selection.extentOffset, testValue.indexOf('g'));
+ }, variant: TargetPlatformVariant.desktop());
+
testWidgets('Can select text by dragging with a mouse', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController();
@@ -15798,7 +15891,7 @@
);
final TextField textField = TextField(
magnifierConfiguration: TextMagnifierConfiguration(
- magnifierBuilder: (_, __, ___) => customMagnifier,
+ magnifierBuilder: (BuildContext context, MagnifierController controller, ValueNotifier<MagnifierInfo>? info) => customMagnifier,
),
);
@@ -15896,7 +15989,7 @@
controller: controller,
magnifierConfiguration: TextMagnifierConfiguration(
magnifierBuilder: (
- _,
+ BuildContext context,
MagnifierController controller,
ValueNotifier<MagnifierInfo> localMagnifierInfo
) {
@@ -15960,7 +16053,7 @@
controller: controller,
magnifierConfiguration: TextMagnifierConfiguration(
magnifierBuilder: (
- _,
+ BuildContext context,
MagnifierController controller,
ValueNotifier<MagnifierInfo> localMagnifierInfo
) {
@@ -16062,7 +16155,7 @@
controller: controller,
magnifierConfiguration: TextMagnifierConfiguration(
magnifierBuilder: (
- _,
+ BuildContext context,
MagnifierController controller,
ValueNotifier<MagnifierInfo> localMagnifierInfo
) {
@@ -16113,6 +16206,54 @@
await tester.pumpAndSettle();
expect(find.byKey(fakeMagnifier.key!), findsNothing);
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.android, TargetPlatform.iOS }));
+
+ testWidgets('magnifier does not show when tapping outside field', (WidgetTester tester) async {
+ // Regression test for https://github.com/flutter/flutter/issues/128321
+ await tester.pumpWidget(
+ MaterialApp(
+ home: Scaffold(
+ body: Padding(
+ padding: const EdgeInsets.all(20),
+ child: TextField(
+ magnifierConfiguration: TextMagnifierConfiguration(
+ magnifierBuilder: (
+ BuildContext context,
+ MagnifierController controller,
+ ValueNotifier<MagnifierInfo> localMagnifierInfo
+ ) {
+ magnifierInfo = localMagnifierInfo;
+ return fakeMagnifier;
+ },
+ ),
+ onTapOutside: (PointerDownEvent event) {
+ FocusManager.instance.primaryFocus?.unfocus();
+ }
+ ),
+ ),
+ ),
+ ),
+ );
+
+ await tester.tapAt(
+ tester.getCenter(find.byType(TextField)),
+ );
+ await tester.pump();
+
+ expect(find.byKey(fakeMagnifier.key!), findsNothing);
+
+ final TestGesture gesture = await tester.startGesture(
+ tester.getBottomLeft(find.byType(TextField)) - const Offset(10.0, 20.0),
+ );
+ await tester.pump();
+ expect(find.byKey(fakeMagnifier.key!), findsNothing);
+ await gesture.up();
+ await tester.pump();
+
+ expect(find.byKey(fakeMagnifier.key!), findsNothing);
+ },
+ skip: isContextMenuProvidedByPlatform, // [intended] only applies to platforms where we supply the context menu.
+ variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.android }),
+ );
});
group('TapRegion integration', () {
@@ -16508,7 +16649,7 @@
return MaterialApp(
home: Scaffold(
body: Builder(
- builder: (_) {
+ builder: (BuildContext context) {
return Column(
children: <Widget>[
TextField(
diff --git a/packages/flutter/test/material/tooltip_test.dart b/packages/flutter/test/material/tooltip_test.dart
index f46cef7..84d6371 100644
--- a/packages/flutter/test/material/tooltip_test.dart
+++ b/packages/flutter/test/material/tooltip_test.dart
@@ -2245,6 +2245,130 @@
reason: 'Tooltip should NOT be visible when hovered and tapped, when trigger mode is tap',
);
});
+
+ testWidgetsWithLeakTracking('Tooltip does not rebuild for fade in / fade out animation', (WidgetTester tester) async {
+ await tester.pumpWidget(
+ const MaterialApp(
+ home: Center(
+ child: SizedBox.square(
+ dimension: 10.0,
+ child: Tooltip(
+ message: tooltipText,
+ waitDuration: Duration(seconds: 1),
+ triggerMode: TooltipTriggerMode.longPress,
+ child: SizedBox.expand(),
+ ),
+ ),
+ ),
+ ),
+ );
+ final TooltipState tooltipState = tester.state(find.byType(Tooltip));
+ final Element element = tooltipState.context as Element;
+ // The Tooltip widget itself is almost stateless thus doesn't need
+ // rebuilding.
+ expect(element.dirty, isFalse);
+
+ expect(tooltipState.ensureTooltipVisible(), isTrue);
+ expect(element.dirty, isFalse);
+ await tester.pump(const Duration(seconds: 1));
+ expect(element.dirty, isFalse);
+
+ expect(Tooltip.dismissAllToolTips(), isTrue);
+ expect(element.dirty, isFalse);
+ await tester.pump(const Duration(seconds: 1));
+ expect(element.dirty, isFalse);
+ });
+
+ testWidgets('Tooltip does not initialize animation controller in dispose process', (WidgetTester tester) async {
+ await tester.pumpWidget(
+ const MaterialApp(
+ home: Center(
+ child: Tooltip(
+ message: tooltipText,
+ waitDuration: Duration(seconds: 1),
+ triggerMode: TooltipTriggerMode.longPress,
+ child: SizedBox.square(dimension: 50),
+ ),
+ ),
+ ),
+ );
+
+ await tester.startGesture(tester.getCenter(find.byType(Tooltip)));
+ await tester.pumpWidget(const SizedBox());
+ expect(tester.takeException(), isNull);
+ });
+
+ testWidgets('Tooltip does not crash when showing the tooltip but the OverlayPortal is unmounted, during dispose', (WidgetTester tester) async {
+ await tester.pumpWidget(
+ const MaterialApp(
+ home: SelectionArea(
+ child: Center(
+ child: Tooltip(
+ message: tooltipText,
+ waitDuration: Duration(seconds: 1),
+ triggerMode: TooltipTriggerMode.longPress,
+ child: SizedBox.square(dimension: 50),
+ ),
+ ),
+ ),
+ ),
+ );
+
+ final TooltipState tooltipState = tester.state(find.byType(Tooltip));
+ await tester.startGesture(tester.getCenter(find.byType(Tooltip)));
+ tooltipState.ensureTooltipVisible();
+ await tester.pumpWidget(const SizedBox());
+ expect(tester.takeException(), isNull);
+ });
+
+ testWidgets('Tooltip is not selectable', (WidgetTester tester) async {
+ const String tooltipText = 'AAAAAAAAAAAAAAAAAAAAAAA';
+ String? selectedText;
+ await tester.pumpWidget(
+ MaterialApp(
+ home: SelectionArea(
+ onSelectionChanged: (SelectedContent? content) { selectedText = content?.plainText; },
+ child: const Center(
+ child: Column(
+ children: <Widget>[
+ Text('Select Me'),
+ Tooltip(
+ message: tooltipText,
+ waitDuration: Duration(seconds: 1),
+ triggerMode: TooltipTriggerMode.longPress,
+ child: SizedBox.square(dimension: 50),
+ ),
+ ],
+ ),
+ ),
+ ),
+ ),
+ );
+
+ final TooltipState tooltipState = tester.state(find.byType(Tooltip));
+
+ final Rect textRect = tester.getRect(find.text('Select Me'));
+ final TestGesture gesture = await tester.startGesture(Alignment.centerLeft.alongSize(textRect.size) + textRect.topLeft);
+ // Drag from centerLeft to centerRight to select the text.
+ await tester.pump(const Duration(seconds: 1));
+ await gesture.moveTo(Alignment.centerRight.alongSize(textRect.size) + textRect.topLeft);
+ await tester.pump();
+
+ tooltipState.ensureTooltipVisible();
+ await tester.pump();
+ // Make sure the tooltip becomes visible.
+ expect(find.text(tooltipText), findsOneWidget);
+ assert(selectedText != null);
+
+ final Rect tooltipTextRect = tester.getRect(find.text(tooltipText));
+ // Now drag from centerLeft to centerRight to select the tooltip text.
+ await gesture.moveTo(Alignment.centerLeft.alongSize(tooltipTextRect.size) + tooltipTextRect.topLeft);
+ await tester.pump();
+ await gesture.moveTo(Alignment.centerRight.alongSize(tooltipTextRect.size) + tooltipTextRect.topLeft);
+ await tester.pump();
+
+ expect(selectedText, isNot(contains('A')));
+ });
}
Future<void> setWidgetForTooltipMode(
@@ -2283,5 +2407,5 @@
if (object.debugSemantics != null) {
return object.debugSemantics!;
}
- return _findDebugSemantics(object.parent! as RenderObject);
+ return _findDebugSemantics(object.parent!);
}
diff --git a/packages/flutter/test/material/tooltip_theme_test.dart b/packages/flutter/test/material/tooltip_theme_test.dart
index c658dd5..b2961b6 100644
--- a/packages/flutter/test/material/tooltip_theme_test.dart
+++ b/packages/flutter/test/material/tooltip_theme_test.dart
@@ -1334,5 +1334,5 @@
if (object.debugSemantics != null) {
return object.debugSemantics!;
}
- return findDebugSemantics(object.parent! as RenderObject);
+ return findDebugSemantics(object.parent!);
}
diff --git a/packages/flutter/test/painting/_test_http_request.dart b/packages/flutter/test/painting/_test_http_request.dart
index 8324d9b..ccfbf1d 100644
--- a/packages/flutter/test/painting/_test_http_request.dart
+++ b/packages/flutter/test/painting/_test_http_request.dart
@@ -43,8 +43,6 @@
setRequestHeader: setRequestHeader.toJS,
addEventListener: addEventListener.toJS,
);
- // TODO(srujzs): This is needed for when we reify JS types. Right now, JSAny
- // is a typedef for Object?, but when we reify, it'll be its own type.
final JSAny mock = _mock as JSAny;
createGetter(mock, 'headers', () => headers.jsify());
createGetter(mock,
diff --git a/packages/flutter/test/painting/border_test.dart b/packages/flutter/test/painting/border_test.dart
index db0fdc4..f2f2aeb 100644
--- a/packages/flutter/test/painting/border_test.dart
+++ b/packages/flutter/test/painting/border_test.dart
@@ -402,4 +402,71 @@
await tester.pumpWidget(buildWidget(border: allowedBorderDirectionalVariations, boxShape: BoxShape.circle));
expect(tester.takeException(), isNull);
});
+
+ test('Compound borders with differing preferPaintInteriors', () {
+ expect(ShapeWithInterior().preferPaintInterior, isTrue);
+ expect(ShapeWithoutInterior().preferPaintInterior, isFalse);
+ expect((ShapeWithInterior() + ShapeWithInterior()).preferPaintInterior, isTrue);
+ expect((ShapeWithInterior() + ShapeWithoutInterior()).preferPaintInterior, isFalse);
+ expect((ShapeWithoutInterior() + ShapeWithInterior()).preferPaintInterior, isFalse);
+ expect((ShapeWithoutInterior() + ShapeWithoutInterior()).preferPaintInterior, isFalse);
+ });
+}
+
+class ShapeWithInterior extends ShapeBorder {
+ @override
+ bool get preferPaintInterior => true;
+
+ @override
+ ShapeBorder scale(double t) {
+ return this;
+ }
+
+ @override
+ EdgeInsetsGeometry get dimensions => EdgeInsets.zero;
+
+ @override
+ Path getInnerPath(Rect rect, { TextDirection? textDirection }) {
+ return Path();
+ }
+
+ @override
+ Path getOuterPath(Rect rect, { TextDirection? textDirection }) {
+ return Path();
+ }
+
+ @override
+ void paintInterior(Canvas canvas, Rect rect, Paint paint, { TextDirection? textDirection }) { }
+
+ @override
+ void paint(Canvas canvas, Rect rect, { TextDirection? textDirection }) { }
+}
+
+class ShapeWithoutInterior extends ShapeBorder {
+ @override
+ bool get preferPaintInterior => false;
+
+ @override
+ ShapeBorder scale(double t) {
+ return this;
+ }
+
+ @override
+ EdgeInsetsGeometry get dimensions => EdgeInsets.zero;
+
+ @override
+ Path getInnerPath(Rect rect, { TextDirection? textDirection }) {
+ return Path();
+ }
+
+ @override
+ Path getOuterPath(Rect rect, { TextDirection? textDirection }) {
+ return Path();
+ }
+
+ @override
+ void paintInterior(Canvas canvas, Rect rect, Paint paint, { TextDirection? textDirection }) { }
+
+ @override
+ void paint(Canvas canvas, Rect rect, { TextDirection? textDirection }) { }
}
diff --git a/packages/flutter/test/painting/image_provider_network_image_test.dart b/packages/flutter/test/painting/image_provider_network_image_test.dart
index 10fb270..086ffa5 100644
--- a/packages/flutter/test/painting/image_provider_network_image_test.dart
+++ b/packages/flutter/test/painting/image_provider_network_image_test.dart
@@ -16,6 +16,7 @@
void main() {
TestRenderingFlutterBinding.ensureInitialized();
+ HttpOverrides.global = _FakeHttpOverrides();
Future<Codec> basicDecoder(ImmutableBuffer buffer, {int? cacheWidth, int? cacheHeight, bool? allowUpscaling}) {
return PaintingBinding.instance.instantiateImageCodecFromBuffer(buffer, cacheWidth: cacheWidth, cacheHeight: cacheHeight, allowUpscaling: allowUpscaling ?? false);
@@ -24,12 +25,14 @@
late _FakeHttpClient httpClient;
setUp(() {
+ _FakeHttpOverrides.createHttpClientCalls = 0;
httpClient = _FakeHttpClient();
debugNetworkImageHttpClientProvider = () => httpClient;
});
tearDown(() {
debugNetworkImageHttpClientProvider = null;
+ expect(_FakeHttpOverrides.createHttpClientCalls, 0);
PaintingBinding.instance.imageCache.clear();
PaintingBinding.instance.imageCache.clearLiveImages();
});
@@ -212,6 +215,22 @@
});
}
+/// Override `HttpClient()` to throw an error.
+///
+/// This ensures that these tests never cause a call to the [HttpClient]
+/// constructor.
+///
+/// Regression test for <https://github.com/flutter/flutter/issues/129532>.
+class _FakeHttpOverrides extends HttpOverrides {
+ static int createHttpClientCalls = 0;
+
+ @override
+ HttpClient createHttpClient(SecurityContext? context) {
+ createHttpClientCalls++;
+ throw Exception('This test tried to create an HttpClient.');
+ }
+}
+
class _FakeHttpClient extends Fake implements HttpClient {
final _FakeHttpClientRequest request = _FakeHttpClientRequest();
Object? thrownError;
@@ -224,6 +243,7 @@
return request;
}
}
+
class _FakeHttpClientRequest extends Fake implements HttpClientRequest {
final _FakeHttpClientResponse response = _FakeHttpClientResponse();
diff --git a/packages/flutter/test/painting/image_stream_test.dart b/packages/flutter/test/painting/image_stream_test.dart
index 0f376c6..0c9bc32 100644
--- a/packages/flutter/test/painting/image_stream_test.dart
+++ b/packages/flutter/test/painting/image_stream_test.dart
@@ -26,8 +26,6 @@
@override
Image get image => _image;
- int get imageHandleCount => image.debugGetOpenHandleStackTraces()!.length;
-
FakeFrameInfo clone() {
return FakeFrameInfo(
_duration,
diff --git a/packages/flutter/test/painting/shape_decoration_test.dart b/packages/flutter/test/painting/shape_decoration_test.dart
index 9c6adf1..402aa70 100644
--- a/packages/flutter/test/painting/shape_decoration_test.dart
+++ b/packages/flutter/test/painting/shape_decoration_test.dart
@@ -48,6 +48,14 @@
expect(identical(ShapeDecoration.lerp(shape, shape, 0.5), shape), true);
});
+ test('ShapeDecoration.lerp null a,b', () {
+ const Decoration a = ShapeDecoration(shape: CircleBorder());
+ const Decoration b = ShapeDecoration(shape: RoundedRectangleBorder());
+ expect(Decoration.lerp(a, null, 0.0), a);
+ expect(Decoration.lerp(null, b, 0.0), b);
+ expect(Decoration.lerp(null, null, 0.0), null);
+ });
+
test('ShapeDecoration.lerp and hit test', () {
const Decoration a = ShapeDecoration(shape: CircleBorder());
const Decoration b = ShapeDecoration(shape: RoundedRectangleBorder());
diff --git a/packages/flutter/test/rendering/cached_intrinsics_test.dart b/packages/flutter/test/rendering/cached_intrinsics_test.dart
index 756a496..bc42ef2 100644
--- a/packages/flutter/test/rendering/cached_intrinsics_test.dart
+++ b/packages/flutter/test/rendering/cached_intrinsics_test.dart
@@ -118,7 +118,7 @@
expect(parentData!.offset.dy, -(viewHeight / 2.0));
expect(test.calls, 2); // The layout constraints change will clear the cached data.
- final RenderObject parent = test.parent! as RenderObject;
+ final RenderObject parent = test.parent!;
expect(parent.debugNeedsLayout, false);
// Do not forget notify parent dirty after the cached data be cleared by `layout()`
diff --git a/packages/flutter/test/rendering/editable_test.dart b/packages/flutter/test/rendering/editable_test.dart
index 8093fe6..0a31aa5 100644
--- a/packages/flutter/test/rendering/editable_test.dart
+++ b/packages/flutter/test/rendering/editable_test.dart
@@ -1006,7 +1006,7 @@
editable.painter = null;
editable.paintCount = 0;
- final AbstractNode? parent = editable.parent;
+ final RenderObject? parent = editable.parent;
if (parent is RenderConstrainedBox) {
parent.child = null;
}
@@ -1823,6 +1823,52 @@
rrect: expectedRRect
));
});
+
+ test('getWordAtOffset with a negative position', () {
+ const String text = 'abc';
+ final _FakeEditableTextState delegate = _FakeEditableTextState()
+ ..textEditingValue = const TextEditingValue(text: text);
+ final ViewportOffset viewportOffset = ViewportOffset.zero();
+ final RenderEditable editable = RenderEditable(
+ backgroundCursorColor: Colors.grey,
+ selectionColor: Colors.black,
+ textDirection: TextDirection.ltr,
+ cursorColor: Colors.red,
+ offset: viewportOffset,
+ textSelectionDelegate: delegate,
+ startHandleLayerLink: LayerLink(),
+ endHandleLayerLink: LayerLink(),
+ text: const TextSpan(
+ text: text,
+ style: TextStyle(height: 1.0, fontSize: 10.0),
+ ),
+ );
+
+ layout(editable, onErrors: expectNoFlutterErrors);
+
+ // Cause text metrics to be computed.
+ editable.computeDistanceToActualBaseline(TextBaseline.alphabetic);
+
+ final TextSelection selection;
+ try {
+ selection = editable.getWordAtOffset(const TextPosition(
+ offset: -1,
+ affinity: TextAffinity.upstream,
+ ));
+ } catch (error) {
+ // In debug mode, negative offsets are caught by an assertion.
+ expect(error, isA<AssertionError>());
+ return;
+ }
+
+ // Web's Paragraph.getWordBoundary behaves differently for a negative
+ // position.
+ if (kIsWeb) {
+ expect(selection, const TextSelection.collapsed(offset: 0));
+ } else {
+ expect(selection, const TextSelection.collapsed(offset: text.length));
+ }
+ });
}
class _TestRenderEditable extends RenderEditable {
diff --git a/packages/flutter/test/rendering/localized_fonts_test.dart b/packages/flutter/test/rendering/localized_fonts_test.dart
index b1cbc5e..b7ff7be 100644
--- a/packages/flutter/test/rendering/localized_fonts_test.dart
+++ b/packages/flutter/test/rendering/localized_fonts_test.dart
@@ -15,11 +15,12 @@
void main() {
testWidgets(
- 'RichText TextSpan styles with different locales',
+ 'Material2 - RichText TextSpan styles with different locales',
(WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
+ theme: ThemeData(useMaterial3: false),
supportedLocales: const <Locale>[
Locale('en', 'US'),
Locale('ja'),
@@ -54,16 +55,63 @@
await expectLater(
find.byType(RichText),
- matchesGoldenFile('localized_fonts.rich_text.styled_text_span.png'),
+ matchesGoldenFile('m2_localized_fonts.rich_text.styled_text_span.png'),
);
},
);
testWidgets(
- 'Text with locale-specific glyphs, ambient locale',
+ 'Material3 - RichText TextSpan styles with different locales',
+ (WidgetTester tester) async {
+
+ await tester.pumpWidget(
+ MaterialApp(
+ theme: ThemeData(useMaterial3: true),
+ supportedLocales: const <Locale>[
+ Locale('en', 'US'),
+ Locale('ja'),
+ Locale('zh'),
+ ],
+ home: Builder(
+ builder: (BuildContext context) {
+ const String character = '骨';
+ final TextStyle style = Theme.of(context).textTheme.displayMedium!;
+ return Scaffold(
+ body: Container(
+ padding: const EdgeInsets.all(48.0),
+ alignment: Alignment.center,
+ child: RepaintBoundary(
+ // Expected result can be seen here:
+ // https://user-images.githubusercontent.com/1377460/40503473-faad6f34-5f42-11e8-972b-d83b727c9d0e.png
+ child: RichText(
+ text: TextSpan(
+ children: <TextSpan>[
+ TextSpan(text: character, style: style.copyWith(locale: const Locale('ja'))),
+ TextSpan(text: character, style: style.copyWith(locale: const Locale('zh'))),
+ ],
+ ),
+ ),
+ ),
+ ),
+ );
+ },
+ ),
+ ),
+ );
+
+ await expectLater(
+ find.byType(RichText),
+ matchesGoldenFile('m3_localized_fonts.rich_text.styled_text_span.png'),
+ );
+ },
+ );
+
+ testWidgets(
+ 'Material2 - Text with locale-specific glyphs, ambient locale',
(WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
+ theme: ThemeData(useMaterial3: false),
supportedLocales: const <Locale>[
Locale('en', 'US'),
Locale('ja'),
@@ -111,10 +159,63 @@
);
testWidgets(
- 'Text with locale-specific glyphs, explicit locale',
+ 'Material3 - Text with locale-specific glyphs, ambient locale',
(WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
+ theme: ThemeData(useMaterial3: true),
+ supportedLocales: const <Locale>[
+ Locale('en', 'US'),
+ Locale('ja'),
+ Locale('zh'),
+ ],
+ home: Builder(
+ builder: (BuildContext context) {
+ const String character = '骨';
+ final TextStyle style = Theme.of(context).textTheme.displayMedium!;
+ return Scaffold(
+ body: Container(
+ padding: const EdgeInsets.all(48.0),
+ alignment: Alignment.center,
+ child: RepaintBoundary(
+ // Expected result can be seen here:
+ // https://user-images.githubusercontent.com/1377460/40503473-faad6f34-5f42-11e8-972b-d83b727c9d0e.png
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceEvenly,
+ children: <Widget>[
+ Localizations.override(
+ context: context,
+ locale: const Locale('ja'),
+ child: Text(character, style: style),
+ ),
+ Localizations.override(
+ context: context,
+ locale: const Locale('zh'),
+ child: Text(character, style: style),
+ ),
+ ],
+ ),
+ ),
+ ),
+ );
+ },
+ ),
+ ),
+ );
+
+ await expectLater(
+ find.byType(Row),
+ matchesGoldenFile('m3_localized_fonts.text_ambient_locale.chars.png'),
+ );
+ },
+ );
+
+ testWidgets(
+ 'Material2 - Text with locale-specific glyphs, explicit locale',
+ (WidgetTester tester) async {
+ await tester.pumpWidget(
+ MaterialApp(
+ theme: ThemeData(useMaterial3: false),
supportedLocales: const <Locale>[
Locale('en', 'US'),
Locale('ja'),
@@ -148,9 +249,52 @@
await expectLater(
find.byType(Row),
- matchesGoldenFile('localized_fonts.text_explicit_locale.chars.png'),
+ matchesGoldenFile('m2_localized_fonts.text_explicit_locale.chars.png'),
);
},
);
+ testWidgets(
+ 'Material3 - Text with locale-specific glyphs, explicit locale',
+ (WidgetTester tester) async {
+ await tester.pumpWidget(
+ MaterialApp(
+ theme: ThemeData(useMaterial3: true),
+ supportedLocales: const <Locale>[
+ Locale('en', 'US'),
+ Locale('ja'),
+ Locale('zh'),
+ ],
+ home: Builder(
+ builder: (BuildContext context) {
+ const String character = '骨';
+ final TextStyle style = Theme.of(context).textTheme.displayMedium!;
+ return Scaffold(
+ body: Container(
+ padding: const EdgeInsets.all(48.0),
+ alignment: Alignment.center,
+ child: RepaintBoundary(
+ // Expected result can be seen here:
+ // https://user-images.githubusercontent.com/1377460/40503473-faad6f34-5f42-11e8-972b-d83b727c9d0e.png
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceEvenly,
+ children: <Widget>[
+ Text(character, style: style, locale: const Locale('ja')),
+ Text(character, style: style, locale: const Locale('zh')),
+ ],
+ ),
+ ),
+ ),
+ );
+ },
+ ),
+ ),
+ );
+
+ await expectLater(
+ find.byType(Row),
+ matchesGoldenFile('m3_localized_fonts.text_explicit_locale.chars.png'),
+ );
+ },
+ );
}
diff --git a/packages/flutter/test/rendering/non_normalized_constraints_test.dart b/packages/flutter/test/rendering/non_normalized_constraints_test.dart
new file mode 100644
index 0000000..b57b69b
--- /dev/null
+++ b/packages/flutter/test/rendering/non_normalized_constraints_test.dart
@@ -0,0 +1,43 @@
+// Copyright 2014 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// THIS TEST IS SENSITIVE TO LINE NUMBERS AT THE TOP OF THIS FILE
+
+import 'package:flutter/foundation.dart';
+import 'package:flutter/rendering.dart';
+import 'package:flutter/widgets.dart';
+import 'package:flutter_test/flutter_test.dart';
+
+class RenderFoo extends RenderShiftedBox {
+ RenderFoo({ RenderBox? child }) : super(child);
+
+ @override
+ void performLayout() {
+ child?.layout(const BoxConstraints( // THIS MUST BE LINE 17
+ minWidth: 100.0, maxWidth: 50.0,
+ ));
+ }
+}
+
+class Foo extends SingleChildRenderObjectWidget {
+ const Foo({ super.key, super.child });
+
+ @override
+ RenderFoo createRenderObject(BuildContext context) {
+ return RenderFoo();
+ }
+}
+
+// END OF SENSITIVE SECTION
+
+void main() {
+ testWidgets('Stack parsing in non-normalized constraints error', (WidgetTester tester) async {
+ await tester.pumpWidget(const Foo(child: Placeholder()), Duration.zero, EnginePhase.layout);
+ final Object? exception = tester.takeException();
+ final String text = exception.toString();
+ expect(text, contains('BoxConstraints has non-normalized width constraints.'));
+ expect(text, contains('which probably computed the invalid constraints in question:\n RenderFoo.performLayout ('));
+ expect(text, contains('non_normalized_constraints_test.dart:17:12'));
+ }, skip: kIsWeb); // [intended] stack traces on web are insufficiently predictable
+}
diff --git a/packages/flutter/test/rendering/non_render_object_root_test.dart b/packages/flutter/test/rendering/non_render_object_root_test.dart
deleted file mode 100644
index f5d33d3..0000000
--- a/packages/flutter/test/rendering/non_render_object_root_test.dart
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2014 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'package:flutter/foundation.dart';
-import 'package:flutter/rendering.dart';
-import 'package:flutter_test/flutter_test.dart';
-
-import 'rendering_tester.dart';
-
-class RealRoot extends AbstractNode {
- RealRoot(this.child) {
- adoptChild(child);
- }
-
- final RenderObject child;
-
- @override
- void redepthChildren() {
- redepthChild(child);
- }
-
- @override
- void attach(Object owner) {
- super.attach(owner);
- child.attach(owner as PipelineOwner);
- }
-
- @override
- void detach() {
- super.detach();
- child.detach();
- }
-
- @override
- PipelineOwner? get owner => super.owner as PipelineOwner?;
-
- void layout() {
- child.layout(BoxConstraints.tight(const Size(500.0, 500.0)));
- }
-}
-
-void main() {
- TestRenderingFlutterBinding.ensureInitialized();
-
- test('non-RenderObject roots', () {
- RenderPositionedBox child;
- final RealRoot root = RealRoot(
- child = RenderPositionedBox(
- child: RenderSizedBox(const Size(100.0, 100.0)),
- ),
- );
- root.attach(PipelineOwner());
-
- child.scheduleInitialLayout();
- root.layout();
-
- child.markNeedsLayout();
- root.layout();
- });
-}
diff --git a/packages/flutter/test/rendering/paragraph_test.dart b/packages/flutter/test/rendering/paragraph_test.dart
index db3d19e..8ae7c59 100644
--- a/packages/flutter/test/rendering/paragraph_test.dart
+++ b/packages/flutter/test/rendering/paragraph_test.dart
@@ -821,6 +821,33 @@
expect(paintingContext.canvas.drawnRectPaint!.color, selectionColor);
});
+// Regression test for https://github.com/flutter/flutter/issues/126652.
+ test('paints selection when tap at chinese character', () async {
+ final TestSelectionRegistrar registrar = TestSelectionRegistrar();
+ const Color selectionColor = Color(0xAF6694e8);
+ final RenderParagraph paragraph = RenderParagraph(
+ const TextSpan(text: '你好'),
+ textDirection: TextDirection.ltr,
+ registrar: registrar,
+ selectionColor: selectionColor,
+ );
+ layout(paragraph);
+ final MockPaintingContext paintingContext = MockPaintingContext();
+ paragraph.paint(paintingContext, Offset.zero);
+ expect(paintingContext.canvas.drawnRect, isNull);
+ expect(paintingContext.canvas.drawnRectPaint, isNull);
+
+ for (final Selectable selectable in (paragraph.registrar! as TestSelectionRegistrar).selectables) {
+ selectable.dispatchSelectionEvent(const SelectWordSelectionEvent(globalPosition: Offset(7, 0)));
+ }
+
+ paintingContext.canvas.clear();
+ paragraph.paint(paintingContext, Offset.zero);
+ expect(paintingContext.canvas.drawnRect!.isEmpty, false);
+ expect(paintingContext.canvas.drawnRectPaint!.style, PaintingStyle.fill);
+ expect(paintingContext.canvas.drawnRectPaint!.color, selectionColor);
+ }, skip: isBrowser); // https://github.com/flutter/flutter/issues/61016
+
test('getPositionForOffset works', () async {
final RenderParagraph paragraph = RenderParagraph(const TextSpan(text: '1234567'), textDirection: TextDirection.ltr);
layout(paragraph);
diff --git a/packages/flutter/test/rendering/proxy_box_test.dart b/packages/flutter/test/rendering/proxy_box_test.dart
index 13991f1..38fe9a0 100644
--- a/packages/flutter/test/rendering/proxy_box_test.dart
+++ b/packages/flutter/test/rendering/proxy_box_test.dart
@@ -803,10 +803,10 @@
});
test('Offstage implements paintsChild correctly', () {
- final RenderBox box = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 20));
- final RenderBox parent = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 20));
+ final RenderConstrainedBox box = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 20));
+ final RenderConstrainedBox parent = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 20));
final RenderOffstage offstage = RenderOffstage(offstage: false, child: box);
- parent.adoptChild(offstage);
+ parent.child = offstage;
expect(offstage.paintsChild(box), true);
@@ -817,9 +817,7 @@
test('Opacity implements paintsChild correctly', () {
final RenderBox box = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 20));
- final RenderBox parent = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 20));
final RenderOpacity opacity = RenderOpacity(child: box);
- parent.adoptChild(opacity);
expect(opacity.paintsChild(box), true);
@@ -830,10 +828,8 @@
test('AnimatedOpacity sets paint matrix to zero when alpha == 0', () {
final RenderBox box = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 20));
- final RenderBox parent = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 20));
final AnimationController opacityAnimation = AnimationController(value: 1, vsync: FakeTickerProvider());
final RenderAnimatedOpacity opacity = RenderAnimatedOpacity(opacity: opacityAnimation, child: box);
- parent.adoptChild(opacity);
// Make it listen to the animation.
opacity.attach(PipelineOwner());
@@ -847,10 +843,8 @@
test('AnimatedOpacity sets paint matrix to zero when alpha == 0 (sliver)', () {
final RenderSliver sliver = RenderSliverToBoxAdapter(child: RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 20)));
- final RenderBox parent = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 20));
final AnimationController opacityAnimation = AnimationController(value: 1, vsync: FakeTickerProvider());
final RenderSliverAnimatedOpacity opacity = RenderSliverAnimatedOpacity(opacity: opacityAnimation, sliver: sliver);
- parent.adoptChild(opacity);
// Make it listen to the animation.
opacity.attach(PipelineOwner());
diff --git a/packages/flutter/test/semantics/semantics_update_test.dart b/packages/flutter/test/semantics/semantics_update_test.dart
index 8fffef8..e5a4122 100644
--- a/packages/flutter/test/semantics/semantics_update_test.dart
+++ b/packages/flutter/test/semantics/semantics_update_test.dart
@@ -218,37 +218,13 @@
// Makes sure we don't send the same id twice.
assert(!observations.containsKey(id));
observations[id] = SemanticsNodeUpdateObservation(
- id: id,
- flags: flags,
- actions: actions,
- maxValueLength: maxValueLength,
- currentValueLength: currentValueLength,
- textSelectionBase: textSelectionBase,
- textSelectionExtent: textSelectionExtent,
- platformViewId: platformViewId,
- scrollChildren: scrollChildren,
- scrollIndex: scrollIndex,
- scrollPosition: scrollPosition,
- scrollExtentMax: scrollExtentMax,
- scrollExtentMin: scrollExtentMin,
- elevation: elevation,
- thickness: thickness,
- rect: rect,
label: label,
labelAttributes: labelAttributes,
hint: hint,
hintAttributes: hintAttributes,
value: value,
valueAttributes: valueAttributes,
- increasedValue: increasedValue,
- increasedValueAttributes: increasedValueAttributes,
- decreasedValue: decreasedValue,
- decreasedValueAttributes: decreasedValueAttributes,
- textDirection: textDirection,
- transform: transform,
childrenInTraversalOrder: childrenInTraversalOrder,
- childrenInHitTestOrder: childrenInHitTestOrder,
- additionalActions: additionalActions,
);
}
@@ -262,68 +238,20 @@
class SemanticsNodeUpdateObservation {
const SemanticsNodeUpdateObservation({
- required this.id,
- required this.flags,
- required this.actions,
- required this.maxValueLength,
- required this.currentValueLength,
- required this.textSelectionBase,
- required this.textSelectionExtent,
- required this.platformViewId,
- required this.scrollChildren,
- required this.scrollIndex,
- required this.scrollPosition,
- required this.scrollExtentMax,
- required this.scrollExtentMin,
- required this.elevation,
- required this.thickness,
- required this.rect,
required this.label,
this.labelAttributes,
required this.value,
this.valueAttributes,
- required this.increasedValue,
- this.increasedValueAttributes,
- required this.decreasedValue,
- this.decreasedValueAttributes,
required this.hint,
this.hintAttributes,
- this.textDirection,
- required this.transform,
required this.childrenInTraversalOrder,
- required this.childrenInHitTestOrder,
- required this.additionalActions,
});
- final int id;
- final int flags;
- final int actions;
- final int maxValueLength;
- final int currentValueLength;
- final int textSelectionBase;
- final int textSelectionExtent;
- final int platformViewId;
- final int scrollChildren;
- final int scrollIndex;
- final double scrollPosition;
- final double scrollExtentMax;
- final double scrollExtentMin;
- final double elevation;
- final double thickness;
- final Rect rect;
final String label;
final List<StringAttribute>? labelAttributes;
final String value;
final List<StringAttribute>? valueAttributes;
- final String increasedValue;
- final List<StringAttribute>? increasedValueAttributes;
- final String decreasedValue;
- final List<StringAttribute>? decreasedValueAttributes;
final String hint;
final List<StringAttribute>? hintAttributes;
- final TextDirection? textDirection;
- final Float64List transform;
final Int32List childrenInTraversalOrder;
- final Int32List childrenInHitTestOrder;
- final Int32List additionalActions;
}
diff --git a/packages/flutter/test/services/asset_manifest_test.dart b/packages/flutter/test/services/asset_manifest_test.dart
index c0edd91..c06ffd0 100644
--- a/packages/flutter/test/services/asset_manifest_test.dart
+++ b/packages/flutter/test/services/asset_manifest_test.dart
@@ -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 'dart:convert';
-
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
@@ -73,29 +71,3 @@
expect(manifest.getAssetVariants('invalid asset key'), isNull);
});
}
-
-String createAssetManifestJson(Map<String, List<AssetMetadata>> manifest) {
- final Map<Object, Object> jsonObject = manifest.map(
- (String key, List<AssetMetadata> value) {
- final List<String> variants = value.map((AssetMetadata e) => e.key).toList();
- return MapEntry<String, List<String>>(key, variants);
- }
- );
-
- return json.encode(jsonObject);
-}
-
-ByteData createAssetManifestSmcBin(Map<String, List<AssetMetadata>> manifest) {
- final Map<Object, Object> smcObject = manifest.map(
- (String key, List<AssetMetadata> value) {
- final List<Object> variants = value.map((AssetMetadata variant) => <String, Object?>{
- 'asset': variant.key,
- 'dpr': variant.targetDevicePixelRatio,
- }).toList();
-
- return MapEntry<String, List<Object>>(key, variants);
- }
- );
-
- return const StandardMessageCodec().encodeMessage(smcObject)!;
-}
diff --git a/packages/flutter/test/services/fake_platform_views.dart b/packages/flutter/test/services/fake_platform_views.dart
index 0cf5f36..7d85e93 100644
--- a/packages/flutter/test/services/fake_platform_views.dart
+++ b/packages/flutter/test/services/fake_platform_views.dart
@@ -503,6 +503,7 @@
final Map<dynamic, dynamic> args = call.arguments as Map<dynamic, dynamic>;
final int id = args['id'] as int;
final String viewType = args['viewType'] as String;
+ final Object? params = args['params'];
if (_views.containsKey(id)) {
throw PlatformException(
@@ -522,7 +523,7 @@
await createCompleter!.future;
}
- _views[id] = FakeHtmlPlatformView(id, viewType);
+ _views[id] = FakeHtmlPlatformView(id, viewType, params);
return Future<int?>.sync(() => null);
}
@@ -658,10 +659,11 @@
@immutable
class FakeHtmlPlatformView {
- const FakeHtmlPlatformView(this.id, this.type);
+ const FakeHtmlPlatformView(this.id, this.type, [this.creationParams]);
final int id;
final String type;
+ final Object? creationParams;
@override
bool operator ==(Object other) {
@@ -670,14 +672,15 @@
}
return other is FakeHtmlPlatformView
&& other.id == id
- && other.type == type;
+ && other.type == type
+ && other.creationParams == creationParams;
}
@override
- int get hashCode => Object.hash(id, type);
+ int get hashCode => Object.hash(id, type, creationParams);
@override
String toString() {
- return 'FakeHtmlPlatformView(id: $id, type: $type)';
+ return 'FakeHtmlPlatformView(id: $id, type: $type, params: $creationParams)';
}
}
diff --git a/packages/flutter/test/widgets/animated_grid_test.dart b/packages/flutter/test/widgets/animated_grid_test.dart
index 7a86f65..dcec143 100644
--- a/packages/flutter/test/widgets/animated_grid_test.dart
+++ b/packages/flutter/test/widgets/animated_grid_test.dart
@@ -646,6 +646,45 @@
expect(tester.widget<CustomScrollView>(find.byType(CustomScrollView)).clipBehavior, clipBehavior);
});
+
+ testWidgets('AnimatedGrid applies MediaQuery padding', (WidgetTester tester) async {
+ const EdgeInsets padding = EdgeInsets.all(30.0);
+ EdgeInsets? innerMediaQueryPadding;
+ await tester.pumpWidget(
+ Directionality(
+ textDirection: TextDirection.ltr,
+ child: MediaQuery(
+ data: const MediaQueryData(
+ padding: EdgeInsets.all(30.0),
+ ),
+ child: AnimatedGrid(
+ initialItemCount: 6,
+ gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
+ crossAxisCount: 2,
+ ),
+ itemBuilder: (BuildContext context, int index, Animation<double> animation) {
+ innerMediaQueryPadding = MediaQuery.paddingOf(context);
+ return const Placeholder();
+ },
+ ),
+ ),
+ ),
+ );
+ final Offset topLeft = tester.getTopLeft(find.byType(Placeholder).first);
+ // Automatically apply the top padding into sliver.
+ expect(topLeft, Offset(0.0, padding.top));
+
+ // Scroll to the bottom.
+ await tester.drag(find.byType(AnimatedGrid), const Offset(0.0, -1000.0));
+ await tester.pumpAndSettle();
+
+ final Offset bottomRight = tester.getBottomRight(find.byType(Placeholder).last);
+ // Automatically apply the bottom padding into sliver.
+ expect(bottomRight, Offset(800.0, 600.0 - padding.bottom));
+
+ // Verify that the left/right padding is not applied.
+ expect(innerMediaQueryPadding, const EdgeInsets.symmetric(horizontal: 30.0));
+ });
}
class _StatefulListItem extends StatefulWidget {
diff --git a/packages/flutter/test/widgets/animated_list_test.dart b/packages/flutter/test/widgets/animated_list_test.dart
index 89a6ce6..6e585c9 100644
--- a/packages/flutter/test/widgets/animated_list_test.dart
+++ b/packages/flutter/test/widgets/animated_list_test.dart
@@ -649,6 +649,42 @@
expect(tester.widget<CustomScrollView>(find.byType(CustomScrollView)).shrinkWrap, true);
});
+
+ testWidgets('AnimatedList applies MediaQuery padding', (WidgetTester tester) async {
+ const EdgeInsets padding = EdgeInsets.all(30.0);
+ EdgeInsets? innerMediaQueryPadding;
+ await tester.pumpWidget(
+ Directionality(
+ textDirection: TextDirection.ltr,
+ child: MediaQuery(
+ data: const MediaQueryData(
+ padding: EdgeInsets.all(30.0),
+ ),
+ child: AnimatedList(
+ initialItemCount: 3,
+ itemBuilder: (BuildContext context, int index, Animation<double> animation) {
+ innerMediaQueryPadding = MediaQuery.paddingOf(context);
+ return const Placeholder();
+ },
+ ),
+ ),
+ ),
+ );
+ final Offset topLeft = tester.getTopLeft(find.byType(Placeholder).first);
+ // Automatically apply the top padding into sliver.
+ expect(topLeft, Offset(0.0, padding.top));
+
+ // Scroll to the bottom.
+ await tester.drag(find.byType(AnimatedList), const Offset(0.0, -1000.0));
+ await tester.pumpAndSettle();
+
+ final Offset bottomLeft = tester.getBottomLeft(find.byType(Placeholder).last);
+ // Automatically apply the bottom padding into sliver.
+ expect(bottomLeft, Offset(0.0, 600.0 - padding.bottom));
+
+ // Verify that the left/right padding is not applied.
+ expect(innerMediaQueryPadding, const EdgeInsets.symmetric(horizontal: 30.0));
+ });
}
diff --git a/packages/flutter/test/widgets/async_lifecycle_test.dart b/packages/flutter/test/widgets/async_lifecycle_test.dart
index 62f1e2f..1931520 100644
--- a/packages/flutter/test/widgets/async_lifecycle_test.dart
+++ b/packages/flutter/test/widgets/async_lifecycle_test.dart
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-import 'package:flutter/widgets.dart';
+import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
class InvalidOnInitLifecycleWidget extends StatefulWidget {
@@ -25,9 +25,9 @@
}
class InvalidDidUpdateWidgetLifecycleWidget extends StatefulWidget {
- const InvalidDidUpdateWidgetLifecycleWidget({super.key, required this.id});
+ const InvalidDidUpdateWidgetLifecycleWidget({super.key, required this.color});
- final int id;
+ final Color color;
@override
InvalidDidUpdateWidgetLifecycleWidgetState createState() => InvalidDidUpdateWidgetLifecycleWidgetState();
@@ -41,7 +41,7 @@
@override
Widget build(BuildContext context) {
- return Container();
+ return ColoredBox(color: widget.color);
}
}
@@ -53,8 +53,8 @@
});
testWidgets('async didUpdateWidget throws FlutterError', (WidgetTester tester) async {
- await tester.pumpWidget(const InvalidDidUpdateWidgetLifecycleWidget(id: 1));
- await tester.pumpWidget(const InvalidDidUpdateWidgetLifecycleWidget(id: 2));
+ await tester.pumpWidget(const InvalidDidUpdateWidgetLifecycleWidget(color: Colors.green));
+ await tester.pumpWidget(const InvalidDidUpdateWidgetLifecycleWidget(color: Colors.red));
expect(tester.takeException(), isFlutterError);
});
diff --git a/packages/flutter/test/widgets/autocomplete_test.dart b/packages/flutter/test/widgets/autocomplete_test.dart
index a35d324..cbedb27 100644
--- a/packages/flutter/test/widgets/autocomplete_test.dart
+++ b/packages/flutter/test/widgets/autocomplete_test.dart
@@ -421,6 +421,144 @@
expect(textEditingController.text, lastOptions.elementAt(0));
});
+ group('optionsViewOpenDirection', () {
+ testWidgets('unset (default behavior): open downward', (WidgetTester tester) async {
+ await tester.pumpWidget(
+ MaterialApp(
+ home: Scaffold(
+ body: Center(
+ child: RawAutocomplete<String>(
+ optionsBuilder: (TextEditingValue textEditingValue) => <String>['a'],
+ fieldViewBuilder: (BuildContext context, TextEditingController controller, FocusNode focusNode, VoidCallback onFieldSubmitted) {
+ return TextField(controller: controller, focusNode: focusNode);
+ },
+ optionsViewBuilder: (BuildContext context, AutocompleteOnSelected<String> onSelected, Iterable<String> options) {
+ return const Text('a');
+ },
+ ),
+ ),
+ ),
+ ),
+ );
+ await tester.showKeyboard(find.byType(TextField));
+ expect(tester.getBottomLeft(find.byType(TextField)),
+ offsetMoreOrLessEquals(tester.getTopLeft(find.text('a'))));
+ });
+
+ testWidgets('down: open downward', (WidgetTester tester) async {
+ await tester.pumpWidget(
+ MaterialApp(
+ home: Scaffold(
+ body: Center(
+ child: RawAutocomplete<String>(
+ optionsViewOpenDirection: OptionsViewOpenDirection.down, // ignore: avoid_redundant_argument_values
+ optionsBuilder: (TextEditingValue textEditingValue) => <String>['a'],
+ fieldViewBuilder: (BuildContext context, TextEditingController controller, FocusNode focusNode, VoidCallback onFieldSubmitted) {
+ return TextField(controller: controller, focusNode: focusNode);
+ },
+ optionsViewBuilder: (BuildContext context, AutocompleteOnSelected<String> onSelected, Iterable<String> options) {
+ return const Text('a');
+ },
+ ),
+ ),
+ ),
+ ),
+ );
+ await tester.showKeyboard(find.byType(TextField));
+ expect(tester.getBottomLeft(find.byType(TextField)),
+ offsetMoreOrLessEquals(tester.getTopLeft(find.text('a'))));
+ });
+
+ testWidgets('up: open upward', (WidgetTester tester) async {
+ await tester.pumpWidget(
+ MaterialApp(
+ home: Scaffold(
+ body: Center(
+ child: RawAutocomplete<String>(
+ optionsViewOpenDirection: OptionsViewOpenDirection.up,
+ optionsBuilder: (TextEditingValue textEditingValue) => <String>['a'],
+ fieldViewBuilder: (BuildContext context, TextEditingController controller, FocusNode focusNode, VoidCallback onFieldSubmitted) {
+ return TextField(controller: controller, focusNode: focusNode);
+ },
+ optionsViewBuilder: (BuildContext context, AutocompleteOnSelected<String> onSelected, Iterable<String> options) {
+ return const Text('a');
+ },
+ ),
+ ),
+ ),
+ ),
+ );
+ await tester.showKeyboard(find.byType(TextField));
+ expect(tester.getTopLeft(find.byType(TextField)),
+ offsetMoreOrLessEquals(tester.getBottomLeft(find.text('a'))));
+ });
+
+ group('fieldViewBuilder not passed', () {
+ testWidgets('down', (WidgetTester tester) async {
+ final GlobalKey autocompleteKey = GlobalKey();
+ final TextEditingController controller = TextEditingController();
+ final FocusNode focusNode = FocusNode();
+ await tester.pumpWidget(
+ MaterialApp(
+ home: Scaffold(
+ body: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: <Widget>[
+ TextField(controller: controller, focusNode: focusNode),
+ RawAutocomplete<String>(
+ key: autocompleteKey,
+ textEditingController: controller,
+ focusNode: focusNode,
+ optionsViewOpenDirection: OptionsViewOpenDirection.down, // ignore: avoid_redundant_argument_values
+ optionsBuilder: (TextEditingValue textEditingValue) => <String>['a'],
+ optionsViewBuilder: (BuildContext context, AutocompleteOnSelected<String> onSelected, Iterable<String> options) {
+ return const Text('a');
+ },
+ ),
+ ],
+ ),
+ ),
+ ),
+ );
+ await tester.showKeyboard(find.byType(TextField));
+ expect(tester.getBottomLeft(find.byKey(autocompleteKey)),
+ offsetMoreOrLessEquals(tester.getTopLeft(find.text('a'))));
+ });
+
+ testWidgets('up', (WidgetTester tester) async {
+ final GlobalKey autocompleteKey = GlobalKey();
+ final TextEditingController controller = TextEditingController();
+ final FocusNode focusNode = FocusNode();
+ await tester.pumpWidget(
+ MaterialApp(
+ home: Scaffold(
+ body: Column(
+ mainAxisAlignment: MainAxisAlignment.end,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: <Widget>[
+ RawAutocomplete<String>(
+ key: autocompleteKey,
+ textEditingController: controller,
+ focusNode: focusNode,
+ optionsViewOpenDirection: OptionsViewOpenDirection.up,
+ optionsBuilder: (TextEditingValue textEditingValue) => <String>['a'],
+ optionsViewBuilder: (BuildContext context, AutocompleteOnSelected<String> onSelected, Iterable<String> options) {
+ return const Text('a');
+ },
+ ),
+ TextField(controller: controller, focusNode: focusNode),
+ ],
+ ),
+ ),
+ ),
+ );
+ await tester.showKeyboard(find.byType(TextField));
+ expect(tester.getTopLeft(find.byKey(autocompleteKey)),
+ offsetMoreOrLessEquals(tester.getBottomLeft(find.text('a'))));
+ });
+ });
+ });
+
testWidgets('options follow field when it moves', (WidgetTester tester) async {
final GlobalKey fieldKey = GlobalKey();
final GlobalKey optionsKey = GlobalKey();
diff --git a/packages/flutter/test/widgets/automatic_keep_alive_test.dart b/packages/flutter/test/widgets/automatic_keep_alive_test.dart
index 1daf6f0..eb2718f 100644
--- a/packages/flutter/test/widgets/automatic_keep_alive_test.dart
+++ b/packages/flutter/test/widgets/automatic_keep_alive_test.dart
@@ -600,23 +600,7 @@
}
}
-class RenderBoxKeepAlive extends RenderBox {
- State<StatefulWidget> createState() => AlwaysKeepAliveRenderBoxState();
-}
-
-class AlwaysKeepAliveRenderBoxState extends State<_AlwaysKeepAlive> with AutomaticKeepAliveClientMixin<_AlwaysKeepAlive> {
- @override
- bool get wantKeepAlive => true;
-
- @override
- Widget build(BuildContext context) {
- super.build(context);
- return const SizedBox(
- height: 48.0,
- child: Text('keep me alive'),
- );
- }
-}
+class RenderBoxKeepAlive extends RenderBox { }
mixin KeepAliveParentDataMixinAlt implements KeepAliveParentDataMixin {
@override
@@ -631,14 +615,6 @@
RenderSliverHelpers,
RenderSliverWithKeepAliveMixin {
- RenderSliverMultiBoxAdaptorAlt({
- RenderSliverBoxChildManager? childManager,
- }) : _childManager = childManager;
-
- @protected
- RenderSliverBoxChildManager? get childManager => _childManager;
- final RenderSliverBoxChildManager? _childManager;
-
final List<RenderBox> children = <RenderBox>[];
void insert(RenderBox child, { RenderBox? after }) {
diff --git a/packages/flutter/test/widgets/backdrop_filter_test.dart b/packages/flutter/test/widgets/backdrop_filter_test.dart
index ebc77b1..a112fe9 100644
--- a/packages/flutter/test/widgets/backdrop_filter_test.dart
+++ b/packages/flutter/test/widgets/backdrop_filter_test.dart
@@ -13,9 +13,10 @@
import 'package:flutter_test/flutter_test.dart';
void main() {
- testWidgets("BackdropFilter's cull rect does not shrink", (WidgetTester tester) async {
+ testWidgets("Material2 - BackdropFilter's cull rect does not shrink", (WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
+ theme: ThemeData(useMaterial3: false),
home: Scaffold(
body: Stack(
fit: StackFit.expand,
@@ -46,13 +47,52 @@
);
await expectLater(
find.byType(RepaintBoundary).first,
- matchesGoldenFile('backdrop_filter_test.cull_rect.png'),
+ matchesGoldenFile('m2_backdrop_filter_test.cull_rect.png'),
);
});
- testWidgets('BackdropFilter blendMode on saveLayer', (WidgetTester tester) async {
+ testWidgets("Material3 - BackdropFilter's cull rect does not shrink", (WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
+ theme: ThemeData(useMaterial3: true),
+ home: Scaffold(
+ body: Stack(
+ fit: StackFit.expand,
+ children: <Widget>[
+ Text('0 0 ' * 10000),
+ Center(
+ // ClipRect needed for filtering the 200x200 area instead of the
+ // whole screen.
+ child: ClipRect(
+ child: BackdropFilter(
+ filter: ImageFilter.blur(
+ sigmaX: 5.0,
+ sigmaY: 5.0,
+ ),
+ child: Container(
+ alignment: Alignment.center,
+ width: 200.0,
+ height: 200.0,
+ child: const Text('Hello World'),
+ ),
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ );
+ await expectLater(
+ find.byType(RepaintBoundary).first,
+ matchesGoldenFile('m3_backdrop_filter_test.cull_rect.png'),
+ );
+ });
+
+ testWidgets('Material2 - BackdropFilter blendMode on saveLayer', (WidgetTester tester) async {
+ await tester.pumpWidget(
+ MaterialApp(
+ theme: ThemeData(useMaterial3: false),
home: Scaffold(
body: Opacity(
opacity: 0.9,
@@ -104,7 +144,66 @@
);
await expectLater(
find.byType(RepaintBoundary).first,
- matchesGoldenFile('backdrop_filter_test.saveLayer.blendMode.png'),
+ matchesGoldenFile('m2_backdrop_filter_test.saveLayer.blendMode.png'),
+ );
+ });
+
+ testWidgets('Material3 - BackdropFilter blendMode on saveLayer', (WidgetTester tester) async {
+ await tester.pumpWidget(
+ MaterialApp(
+ theme: ThemeData(useMaterial3: true),
+ home: Scaffold(
+ body: Opacity(
+ opacity: 0.9,
+ child: Stack(
+ fit: StackFit.expand,
+ children: <Widget>[
+ Text('0 0 ' * 10000),
+ Column(
+ mainAxisAlignment: MainAxisAlignment.spaceEvenly,
+ // ClipRect needed for filtering the 200x200 area instead of the
+ // whole screen.
+ children: <Widget>[
+ ClipRect(
+ child: BackdropFilter(
+ filter: ImageFilter.blur(
+ sigmaX: 5.0,
+ sigmaY: 5.0,
+ ),
+ child: Container(
+ alignment: Alignment.center,
+ width: 200.0,
+ height: 200.0,
+ color: Colors.yellow.withAlpha(0x7),
+ ),
+ ),
+ ),
+ ClipRect(
+ child: BackdropFilter(
+ filter: ImageFilter.blur(
+ sigmaX: 5.0,
+ sigmaY: 5.0,
+ ),
+ blendMode: BlendMode.src,
+ child: Container(
+ alignment: Alignment.center,
+ width: 200.0,
+ height: 200.0,
+ color: Colors.yellow.withAlpha(0x7),
+ ),
+ ),
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ ),
+ ),
+ );
+ await expectLater(
+ find.byType(RepaintBoundary).first,
+ matchesGoldenFile('m3_backdrop_filter_test.saveLayer.blendMode.png'),
);
});
}
diff --git a/packages/flutter/test/widgets/basic_test.dart b/packages/flutter/test/widgets/basic_test.dart
index 8b35975..5fb6bc8 100644
--- a/packages/flutter/test/widgets/basic_test.dart
+++ b/packages/flutter/test/widgets/basic_test.dart
@@ -463,6 +463,7 @@
await tester.pumpWidget(
MaterialApp(
+ theme: ThemeData(useMaterial3: false),
home: Scaffold(
body: Row(
crossAxisAlignment: CrossAxisAlignment.baseline,
@@ -470,11 +471,11 @@
children: <Widget>[
Text('big text',
key: key1,
- style: const TextStyle(fontFamily: 'FlutterTest', fontSize: fontSize1),
+ style: const TextStyle(fontFamily: 'FlutterTest', fontSize: fontSize1, height: 1.0),
),
Text('one\ntwo\nthree\nfour\nfive\nsix\nseven',
key: key2,
- style: const TextStyle(fontFamily: 'FlutterTest', fontSize: fontSize2),
+ style: const TextStyle(fontFamily: 'FlutterTest', fontSize: fontSize2, height: 1.0),
),
],
),
@@ -517,6 +518,7 @@
await tester.pumpWidget(
MaterialApp(
+ theme: ThemeData(useMaterial3: false),
home: Scaffold(
body: Row(
crossAxisAlignment: CrossAxisAlignment.baseline,
@@ -524,11 +526,11 @@
children: <Widget>[
Text('big text',
key: key1,
- style: const TextStyle(fontFamily: 'FlutterTest', fontSize: fontSize1),
+ style: const TextStyle(fontFamily: 'FlutterTest', fontSize: fontSize1, height: 1.0),
),
Text('one\ntwo\nthree\nfour\nfive\nsix\nseven',
key: key2,
- style: const TextStyle(fontFamily: 'FlutterTest', fontSize: fontSize2),
+ style: const TextStyle(fontFamily: 'FlutterTest', fontSize: fontSize2, height: 1.0),
),
const FlutterLogo(size: 250),
],
diff --git a/packages/flutter/test/widgets/color_filter_test.dart b/packages/flutter/test/widgets/color_filter_test.dart
index 153e6d8..3135844 100644
--- a/packages/flutter/test/widgets/color_filter_test.dart
+++ b/packages/flutter/test/widgets/color_filter_test.dart
@@ -41,7 +41,7 @@
colorFilter: sepia,
child: MaterialApp(
title: 'Flutter Demo',
- theme: ThemeData(primarySwatch: Colors.blue),
+ theme: ThemeData(primarySwatch: Colors.blue, useMaterial3: false),
home: Scaffold(
appBar: AppBar(
title: const Text('Sepia ColorFilter Test'),
diff --git a/packages/flutter/test/widgets/decorated_sliver_test.dart b/packages/flutter/test/widgets/decorated_sliver_test.dart
new file mode 100644
index 0000000..a3d328f
--- /dev/null
+++ b/packages/flutter/test/widgets/decorated_sliver_test.dart
@@ -0,0 +1,504 @@
+// Copyright 2014 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file is run as part of a reduced test set in CI on Mac and Windows
+// machines.
+@Tags(<String>['reduced-test-set'])
+library;
+
+import 'package:flutter/material.dart';
+import 'package:flutter_test/flutter_test.dart';
+
+import '../rendering/mock_canvas.dart';
+
+void main() {
+ testWidgets('DecoratedSliver creates, paints, and disposes BoxPainter', (WidgetTester tester) async {
+ final TestDecoration decoration = TestDecoration();
+ await tester.pumpWidget(MaterialApp(
+ home: Scaffold(
+ body: CustomScrollView(
+ slivers: <Widget>[
+ DecoratedSliver(
+ decoration: decoration,
+ sliver: const SliverToBoxAdapter(
+ child: SizedBox(width: 100, height: 100),
+ ),
+ )
+ ],
+ )
+ )
+ ));
+
+ expect(decoration.painters, hasLength(1));
+ expect(decoration.painters.last.lastConfiguration!.size, const Size(800, 100));
+ expect(decoration.painters.last.lastOffset, Offset.zero);
+ expect(decoration.painters.last.disposed, false);
+
+ await tester.pumpWidget(const SizedBox());
+
+ expect(decoration.painters, hasLength(1));
+ expect(decoration.painters.last.disposed, true);
+ });
+
+ testWidgets('DecoratedSliver can update box painter', (WidgetTester tester) async {
+ final TestDecoration decorationA = TestDecoration();
+ final TestDecoration decorationB = TestDecoration();
+
+ Decoration activateDecoration = decorationA;
+ late StateSetter localSetState;
+ await tester.pumpWidget(MaterialApp(
+ home: Scaffold(
+ body: StatefulBuilder(
+ builder: (BuildContext context, StateSetter setState) {
+ localSetState = setState;
+ return CustomScrollView(
+ slivers: <Widget>[
+ DecoratedSliver(
+ decoration: activateDecoration,
+ sliver: const SliverToBoxAdapter(
+ child: SizedBox(width: 100, height: 100),
+ ),
+ )
+ ],
+ );
+ },
+ )
+ )
+ ));
+
+ expect(decorationA.painters, hasLength(1));
+ expect(decorationA.painters.last.paintCount, 1);
+ expect(decorationB.painters, hasLength(0));
+
+ localSetState(() {
+ activateDecoration = decorationB;
+ });
+ await tester.pump();
+
+ expect(decorationA.painters, hasLength(1));
+ expect(decorationB.painters, hasLength(1));
+ expect(decorationB.painters.last.paintCount, 1);
+ });
+
+ testWidgets('DecoratedSliver can update DecorationPosition', (WidgetTester tester) async {
+ final TestDecoration decoration = TestDecoration();
+
+ DecorationPosition activePosition = DecorationPosition.foreground;
+ late StateSetter localSetState;
+ await tester.pumpWidget(MaterialApp(
+ home: Scaffold(
+ body: StatefulBuilder(
+ builder: (BuildContext context, StateSetter setState) {
+ localSetState = setState;
+ return CustomScrollView(
+ slivers: <Widget>[
+ DecoratedSliver(
+ decoration: decoration,
+ position: activePosition,
+ sliver: const SliverToBoxAdapter(
+ child: SizedBox(width: 100, height: 100),
+ ),
+ )
+ ],
+ );
+ },
+ )
+ )
+ ));
+
+ expect(decoration.painters, hasLength(1));
+ expect(decoration.painters.last.paintCount, 1);
+
+ localSetState(() {
+ activePosition = DecorationPosition.background;
+ });
+ await tester.pump();
+
+ expect(decoration.painters, hasLength(1));
+ expect(decoration.painters.last.paintCount, 2);
+ });
+
+ testWidgets('DecoratedSliver golden test', (WidgetTester tester) async {
+ const BoxDecoration decoration = BoxDecoration(
+ color: Colors.blue,
+ );
+
+ final Key backgroundKey = UniqueKey();
+ await tester.pumpWidget(MaterialApp(
+ home: Scaffold(
+ body: RepaintBoundary(
+ key: backgroundKey,
+ child: CustomScrollView(
+ slivers: <Widget>[
+ DecoratedSliver(
+ decoration: decoration,
+ sliver: SliverPadding(
+ padding: const EdgeInsets.all(16),
+ sliver: SliverList(
+ delegate: SliverChildListDelegate.fixed(<Widget>[
+ Container(
+ height: 100,
+ color: Colors.red,
+ ),
+ Container(
+ height: 100,
+ color: Colors.yellow,
+ ),
+ Container(
+ height: 100,
+ color: Colors.red,
+ ),
+ ]),
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ )
+ ));
+
+ await expectLater(find.byKey(backgroundKey), matchesGoldenFile('decorated_sliver.moon.background.png'));
+
+ final Key foregroundKey = UniqueKey();
+ await tester.pumpWidget(MaterialApp(
+ home: Scaffold(
+ body: RepaintBoundary(
+ key: foregroundKey,
+ child: CustomScrollView(
+ slivers: <Widget>[
+ DecoratedSliver(
+ decoration: decoration,
+ position: DecorationPosition.foreground,
+ sliver: SliverPadding(
+ padding: const EdgeInsets.all(16),
+ sliver: SliverList(
+ delegate: SliverChildListDelegate.fixed(<Widget>[
+ Container(
+ height: 100,
+ color: Colors.red,
+ ),
+ Container(
+ height: 100,
+ color: Colors.yellow,
+ ),
+ Container(
+ height: 100,
+ color: Colors.red,
+ ),
+ ]),
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ )
+ ));
+
+ await expectLater(find.byKey(foregroundKey), matchesGoldenFile('decorated_sliver.moon.foreground.png'));
+ });
+
+ testWidgets('DecoratedSliver paints its border correctly vertically', (WidgetTester tester) async {
+ const Key key = Key('DecoratedSliver with border');
+ const Color black = Color(0xFF000000);
+ final ScrollController controller = ScrollController();
+ await tester.pumpWidget(Directionality(
+ textDirection: TextDirection.ltr,
+ child: Align(
+ alignment: Alignment.topLeft,
+ child: SizedBox(
+ height: 300,
+ width: 100,
+ child: CustomScrollView(
+ controller: controller,
+ slivers: <Widget>[
+ DecoratedSliver(
+ key: key,
+ decoration: BoxDecoration(border: Border.all()),
+ sliver: const SliverToBoxAdapter(
+ child: SizedBox(width: 100, height: 500),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ ));
+ controller.jumpTo(200);
+ await tester.pumpAndSettle();
+ expect(find.byKey(key), paints..rect(
+ rect: const Offset(0.5, -199.5) & const Size(99, 499),
+ color: black,
+ style: PaintingStyle.stroke,
+ strokeWidth: 1.0,
+ ));
+ });
+
+ testWidgets('DecoratedSliver paints its border correctly vertically reverse', (WidgetTester tester) async {
+ const Key key = Key('DecoratedSliver with border');
+ const Color black = Color(0xFF000000);
+ final ScrollController controller = ScrollController();
+ await tester.pumpWidget(Directionality(
+ textDirection: TextDirection.ltr,
+ child: Align(
+ alignment: Alignment.topLeft,
+ child: SizedBox(
+ height: 300,
+ width: 100,
+ child: CustomScrollView(
+ controller: controller,
+ reverse: true,
+ slivers: <Widget>[
+ DecoratedSliver(
+ key: key,
+ decoration: BoxDecoration(border: Border.all()),
+ sliver: const SliverToBoxAdapter(
+ child: SizedBox(width: 100, height: 500),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ ));
+ controller.jumpTo(200);
+ await tester.pumpAndSettle();
+ expect(find.byKey(key), paints..rect(
+ rect: const Offset(0.5, -199.5) & const Size(99, 499),
+ color: black,
+ style: PaintingStyle.stroke,
+ strokeWidth: 1.0,
+ ));
+ });
+
+
+
+ testWidgets('DecoratedSliver paints its border correctly horizontally', (WidgetTester tester) async {
+ const Key key = Key('DecoratedSliver with border');
+ const Color black = Color(0xFF000000);
+ final ScrollController controller = ScrollController();
+ await tester.pumpWidget(Directionality(
+ textDirection: TextDirection.ltr,
+ child: Align(
+ alignment: Alignment.topLeft,
+ child: SizedBox(
+ height: 100,
+ width: 300,
+ child: CustomScrollView(
+ scrollDirection: Axis.horizontal,
+ controller: controller,
+ slivers: <Widget>[
+ DecoratedSliver(
+ key: key,
+ decoration: BoxDecoration(border: Border.all()),
+ sliver: const SliverToBoxAdapter(
+ child: SizedBox(width: 500, height: 100),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ ));
+ controller.jumpTo(200);
+ await tester.pumpAndSettle();
+ expect(find.byKey(key), paints..rect(
+ rect: const Offset(-199.5, 0.5) & const Size(499, 99),
+ color: black,
+ style: PaintingStyle.stroke,
+ strokeWidth: 1.0,
+ ));
+ });
+
+ testWidgets('DecoratedSliver paints its border correctly horizontally reverse', (WidgetTester tester) async {
+ const Key key = Key('DecoratedSliver with border');
+ const Color black = Color(0xFF000000);
+ final ScrollController controller = ScrollController();
+ await tester.pumpWidget(Directionality(
+ textDirection: TextDirection.ltr,
+ child: Align(
+ alignment: Alignment.topLeft,
+ child: SizedBox(
+ height: 100,
+ width: 300,
+ child: CustomScrollView(
+ scrollDirection: Axis.horizontal,
+ reverse: true,
+ controller: controller,
+ slivers: <Widget>[
+ DecoratedSliver(
+ key: key,
+ decoration: BoxDecoration(border: Border.all()),
+ sliver: const SliverToBoxAdapter(
+ child: SizedBox(width: 500, height: 100),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ ));
+ controller.jumpTo(200);
+ await tester.pumpAndSettle();
+ expect(find.byKey(key), paints..rect(
+ rect: const Offset(-199.5, 0.5) & const Size(499, 99),
+ color: black,
+ style: PaintingStyle.stroke,
+ strokeWidth: 1.0,
+ ));
+ });
+
+
+ testWidgets('DecoratedSliver works with SliverMainAxisGroup', (WidgetTester tester) async {
+ const Key key = Key('DecoratedSliver with border');
+ const Color black = Color(0xFF000000);
+ final ScrollController controller = ScrollController();
+ await tester.pumpWidget(Directionality(
+ textDirection: TextDirection.ltr,
+ child: Align(
+ alignment: Alignment.topLeft,
+ child: SizedBox(
+ height: 100,
+ width: 300,
+ child: CustomScrollView(
+ controller: controller,
+ slivers: <Widget>[
+ DecoratedSliver(
+ key: key,
+ decoration: BoxDecoration(border: Border.all()),
+ sliver: const SliverMainAxisGroup(
+ slivers: <Widget>[
+ SliverToBoxAdapter(child: SizedBox(height: 100)),
+ SliverToBoxAdapter(child: SizedBox(height: 100)),
+ ],
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ ));
+ await tester.pumpAndSettle();
+ expect(find.byKey(key), paints..rect(
+ rect: const Offset(0.5, 0.5) & const Size(299, 199),
+ color: black,
+ style: PaintingStyle.stroke,
+ strokeWidth: 1.0,
+ ));
+ });
+
+ testWidgets('DecoratedSliver works with SliverCrossAxisGroup', (WidgetTester tester) async {
+ const Key key = Key('DecoratedSliver with border');
+ const Color black = Color(0xFF000000);
+ final ScrollController controller = ScrollController();
+ await tester.pumpWidget(Directionality(
+ textDirection: TextDirection.ltr,
+ child: Align(
+ alignment: Alignment.topLeft,
+ child: SizedBox(
+ height: 100,
+ width: 300,
+ child: CustomScrollView(
+ controller: controller,
+ slivers: <Widget>[
+ DecoratedSliver(
+ key: key,
+ decoration: BoxDecoration(border: Border.all()),
+ sliver: const SliverCrossAxisGroup(
+ slivers: <Widget>[
+ SliverToBoxAdapter(child: SizedBox(height: 100)),
+ SliverToBoxAdapter(child: SizedBox(height: 100)),
+ ],
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ ));
+ await tester.pumpAndSettle();
+ expect(find.byKey(key), paints..rect(
+ rect: const Offset(0.5, 0.5) & const Size(299, 99),
+ color: black,
+ style: PaintingStyle.stroke,
+ strokeWidth: 1.0,
+ ));
+ });
+
+ testWidgets('DecoratedSliver draws only up to the bottom cache when sliver has infinite scroll extent', (WidgetTester tester) async {
+ const Key key = Key('DecoratedSliver with border');
+ const Color black = Color(0xFF000000);
+ final ScrollController controller = ScrollController();
+ await tester.pumpWidget(Directionality(
+ textDirection: TextDirection.ltr,
+ child: Align(
+ alignment: Alignment.topLeft,
+ child: SizedBox(
+ height: 100,
+ width: 300,
+ child: CustomScrollView(
+ controller: controller,
+ slivers: <Widget>[
+ DecoratedSliver(
+ key: key,
+ decoration: BoxDecoration(border: Border.all()),
+ sliver: SliverList.builder(
+ itemBuilder: (BuildContext context, int index) => const SizedBox(height: 100),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ ));
+ expect(find.byKey(key), paints..rect(
+ rect: const Offset(0.5, 0.5) & const Size(299, 349),
+ color: black,
+ style: PaintingStyle.stroke,
+ strokeWidth: 1.0,
+ ));
+ controller.jumpTo(200);
+ await tester.pumpAndSettle();
+ // Note that the bottom edge is of the rect is the same as above.
+ expect(find.byKey(key), paints..rect(
+ rect: const Offset(0.5, -199.5) & const Size(299, 549),
+ color: black,
+ style: PaintingStyle.stroke,
+ strokeWidth: 1.0,
+ ));
+ });
+}
+
+class TestDecoration extends Decoration {
+ final List<TestBoxPainter> painters = <TestBoxPainter>[];
+
+ @override
+ BoxPainter createBoxPainter([VoidCallback? onChanged]) {
+ final TestBoxPainter painter = TestBoxPainter();
+ painters.add(painter);
+ return painter;
+ }
+}
+
+class TestBoxPainter extends BoxPainter {
+ Offset? lastOffset;
+ ImageConfiguration? lastConfiguration;
+ bool disposed = false;
+ int paintCount = 0;
+
+ @override
+ void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {
+ lastOffset = offset;
+ lastConfiguration = configuration;
+ paintCount += 1;
+ }
+
+ @override
+ void dispose() {
+ assert(!disposed);
+ disposed = true;
+ super.dispose();
+ }
+}
diff --git a/packages/flutter/test/widgets/editable_text_cursor_test.dart b/packages/flutter/test/widgets/editable_text_cursor_test.dart
index 3db3d48..62640cb 100644
--- a/packages/flutter/test/widgets/editable_text_cursor_test.dart
+++ b/packages/flutter/test/widgets/editable_text_cursor_test.dart
@@ -927,6 +927,7 @@
await tester.pumpWidget(
MaterialApp(
+ theme: ThemeData(useMaterial3: false),
home: Padding(
padding: const EdgeInsets.only(top: 0.25),
child: Material(
diff --git a/packages/flutter/test/widgets/editable_text_show_on_screen_test.dart b/packages/flutter/test/widgets/editable_text_show_on_screen_test.dart
index db23cc8..2c4a9ed 100644
--- a/packages/flutter/test/widgets/editable_text_show_on_screen_test.dart
+++ b/packages/flutter/test/widgets/editable_text_show_on_screen_test.dart
@@ -276,7 +276,7 @@
final ScrollController scrollController = ScrollController();
final TextEditingController controller = TextEditingController();
final FocusNode focusNode = FocusNode();
- controller.text = 'Start\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nEnd';
+ controller.text = "Start${'\n' * 39}End";
await tester.pumpWidget(MaterialApp(
home: Center(
@@ -322,6 +322,58 @@
expect(scrollController.offset, greaterThan(0.0));
});
+ testWidgets('focused multi-line editable does not scroll to old position when non-collapsed selection set', (WidgetTester tester) async {
+ final ScrollController scrollController = ScrollController();
+ final TextEditingController controller = TextEditingController();
+ final FocusNode focusNode = FocusNode();
+ final String text = "Start${'\n' * 39}End";
+ controller.value = TextEditingValue(text: text, selection: TextSelection.collapsed(offset: text.length - 3));
+
+ await tester.pumpWidget(MaterialApp(
+ home: Center(
+ child: SizedBox(
+ height: 300.0,
+ child: ListView(
+ controller: scrollController,
+ children: <Widget>[
+ EditableText(
+ backgroundCursorColor: Colors.grey,
+ maxLines: null, // multiline
+ controller: controller,
+ focusNode: focusNode,
+ style: textStyle,
+ cursorColor: cursorColor,
+ ),
+ ],
+ ),
+ ),
+ ),
+ ));
+
+ // Bring keyboard up and verify that end of EditableText is not on screen.
+ await tester.showKeyboard(find.byType(EditableText));
+ await tester.pumpAndSettle();
+
+ scrollController.jumpTo(0.0);
+ await tester.pumpAndSettle();
+ final RenderBox render = tester.renderObject(find.byType(EditableText));
+ expect(render.size.height, greaterThan(500.0));
+ expect(scrollController.offset, 0.0);
+
+ // Change selection to non-collapased so that cursor isn't shown
+ // and the location requires a bit of scroll.
+ tester.testTextInput.updateEditingValue(TextEditingValue(
+ text: text,
+ selection: const TextSelection(baseOffset: 26, extentOffset: 27),
+ ));
+ await tester.pumpAndSettle();
+
+ // Selection extent scrolls into view.
+ expect(find.byType(EditableText), findsOneWidget);
+ expect(render.size.height, greaterThan(500.0));
+ expect(scrollController.offset, 28.0);
+ });
+
testWidgets('scrolls into view with scrollInserts after the keyboard pops up', (WidgetTester tester) async {
final ScrollController scrollController = ScrollController();
final TextEditingController controller = TextEditingController();
diff --git a/packages/flutter/test/widgets/editable_text_test.dart b/packages/flutter/test/widgets/editable_text_test.dart
index b81f8cf..4cc86a0 100644
--- a/packages/flutter/test/widgets/editable_text_test.dart
+++ b/packages/flutter/test/widgets/editable_text_test.dart
@@ -15,6 +15,7 @@
import '../rendering/mock_canvas.dart';
import '../widgets/clipboard_utils.dart';
import 'editable_text_utils.dart';
+import 'live_text_utils.dart';
import 'semantics_tester.dart';
Matcher matchesMethodCall(String method, { dynamic args }) => _MatchesMethodCall(method, arguments: args == null ? null : wrapMatcher(args));
@@ -118,6 +119,72 @@
expect(tester.testTextInput.setClientArgs!['inputAction'], equals(serializedActionName));
}
+ testWidgets(
+ 'Tapping the Live Text button calls onLiveTextInput',
+ (WidgetTester tester) async {
+ bool invokedLiveTextInputSuccessfully = false;
+ final GlobalKey key = GlobalKey();
+ final TextEditingController controller = TextEditingController(text: '');
+ await tester.pumpWidget(
+ MaterialApp(
+ home: Align(
+ alignment: Alignment.topLeft,
+ child: SizedBox(
+ width: 400,
+ child: EditableText(
+ maxLines: 10,
+ controller: controller,
+ showSelectionHandles: true,
+ autofocus: true,
+ focusNode: FocusNode(),
+ style: Typography.material2018().black.subtitle1!,
+ cursorColor: Colors.blue,
+ backgroundCursorColor: Colors.grey,
+ keyboardType: TextInputType.text,
+ textAlign: TextAlign.right,
+ selectionControls: materialTextSelectionHandleControls,
+ contextMenuBuilder: (
+ BuildContext context,
+ EditableTextState editableTextState,
+ ) {
+ return CupertinoAdaptiveTextSelectionToolbar.editable(
+ key: key,
+ clipboardStatus: ClipboardStatus.pasteable,
+ onCopy: null,
+ onCut: null,
+ onPaste: null,
+ onSelectAll: null,
+ onLiveTextInput: () {
+ invokedLiveTextInputSuccessfully = true;
+ },
+ anchors: const TextSelectionToolbarAnchors(primaryAnchor: Offset.zero),
+ );
+ },
+ ),
+ ),
+ ),
+ ),
+ );
+
+ await tester.pump(); // Wait for autofocus to take effect.
+
+ expect(find.byKey(key), findsNothing);
+
+ // Long-press to bring up the context menu.
+ final Finder textFinder = find.byType(EditableText);
+ await tester.longPress(textFinder);
+ tester.state<EditableTextState>(textFinder).showToolbar();
+ await tester.pumpAndSettle();
+
+ expect(find.byKey(key), findsOneWidget);
+ expect(findLiveTextButton(), findsOneWidget);
+ await tester.tap(findLiveTextButton());
+ await tester.pump();
+ expect(invokedLiveTextInputSuccessfully, isTrue);
+ },
+ skip: kIsWeb, // [intended]
+ );
+
// Regression test for https://github.com/flutter/flutter/issues/126312.
testWidgets('when open input connection in didUpdateWidget, should not throw', (WidgetTester tester) async {
final Key key = GlobalKey();
@@ -9652,7 +9719,7 @@
expect(tester.takeException(), isNull);
await tester.pumpWidget(Container());
- expect(tester.takeException(), isNotNull);
+ expect(tester.takeException(), isAssertionError);
});
});
diff --git a/packages/flutter/test/widgets/fade_in_image_test.dart b/packages/flutter/test/widgets/fade_in_image_test.dart
index 94933c1..a10a77b 100644
--- a/packages/flutter/test/widgets/fade_in_image_test.dart
+++ b/packages/flutter/test/widgets/fade_in_image_test.dart
@@ -30,16 +30,6 @@
expect(animatedFadeOutFadeInElement, isNotNull);
return animatedFadeOutFadeInElement!.state;
}
-
- Element? get semanticsElement {
- Element? result;
- fadeInImageElement.visitChildren((Element child) {
- if (child.widget is Semantics) {
- result = child;
- }
- });
- return result;
- }
}
class FadeInImageElements {
diff --git a/packages/flutter/test/widgets/framework_test.dart b/packages/flutter/test/widgets/framework_test.dart
index 11e445a..4d82aa8 100644
--- a/packages/flutter/test/widgets/framework_test.dart
+++ b/packages/flutter/test/widgets/framework_test.dart
@@ -1592,13 +1592,13 @@
builder.properties.any((DiagnosticsNode property) => property.name == 'dependencies' && property.value != null),
isTrue,
);
- final DiagnosticsProperty<List<DiagnosticsNode>> dependenciesProperty =
- builder.properties.firstWhere((DiagnosticsNode property) => property.name == 'dependencies') as DiagnosticsProperty<List<DiagnosticsNode>>;
+ final DiagnosticsProperty<Set<InheritedElement>> dependenciesProperty =
+ builder.properties.firstWhere((DiagnosticsNode property) => property.name == 'dependencies') as DiagnosticsProperty<Set<InheritedElement>>;
expect(dependenciesProperty, isNotNull);
- final List<DiagnosticsNode> dependencies = dependenciesProperty.value!;
+ final Set<InheritedElement> dependencies = dependenciesProperty.value!;
expect(dependencies.length, equals(3));
- expect(dependencies.toString(), '[ButtonBarTheme, Directionality, FocusTraversalOrder]');
+ expect(dependenciesProperty.toDescription(), '[ButtonBarTheme, Directionality, FocusTraversalOrder]');
});
testWidgets('BuildOwner.globalKeyCount keeps track of in-use global keys', (WidgetTester tester) async {
diff --git a/packages/flutter/test/widgets/heroes_test.dart b/packages/flutter/test/widgets/heroes_test.dart
index 5dbc959..463f5ba 100644
--- a/packages/flutter/test/widgets/heroes_test.dart
+++ b/packages/flutter/test/widgets/heroes_test.dart
@@ -1188,7 +1188,7 @@
if (currentNode is RenderAnimatedOpacity && currentNode.opacity.value == 0) {
return false;
}
- currentNode = currentNode.parent as RenderObject?;
+ currentNode = currentNode.parent;
}
return true;
}
@@ -2919,7 +2919,7 @@
final ScrollController controller = ScrollController();
RenderAnimatedOpacity? findRenderAnimatedOpacity() {
- AbstractNode? parent = tester.renderObject(find.byType(Placeholder));
+ RenderObject? parent = tester.renderObject(find.byType(Placeholder));
while (parent is RenderObject && parent is! RenderAnimatedOpacity) {
parent = parent.parent;
}
diff --git a/packages/flutter/test/widgets/html_element_view_test.dart b/packages/flutter/test/widgets/html_element_view_test.dart
index 4b58794..b485aef 100644
--- a/packages/flutter/test/widgets/html_element_view_test.dart
+++ b/packages/flutter/test/widgets/html_element_view_test.dart
@@ -73,6 +73,42 @@
);
});
+ testWidgets('Create HTML view with creation params', (WidgetTester tester) async {
+ final int currentViewId = platformViewsRegistry.getNextPlatformViewId();
+ final FakeHtmlPlatformViewsController viewsController = FakeHtmlPlatformViewsController();
+ viewsController.registerViewType('webview');
+ await tester.pumpWidget(
+ const Column(
+ children: <Widget>[
+ SizedBox(
+ width: 200.0,
+ height: 100.0,
+ child: HtmlElementView(
+ viewType: 'webview',
+ creationParams: 'foobar',
+ ),
+ ),
+ SizedBox(
+ width: 200.0,
+ height: 100.0,
+ child: HtmlElementView(
+ viewType: 'webview',
+ creationParams: 123,
+ ),
+ ),
+ ],
+ ),
+ );
+
+ expect(
+ viewsController.views,
+ unorderedEquals(<FakeHtmlPlatformView>[
+ FakeHtmlPlatformView(currentViewId + 1, 'webview', 'foobar'),
+ FakeHtmlPlatformView(currentViewId + 2, 'webview', 123),
+ ]),
+ );
+ });
+
testWidgets('Resize HTML view', (WidgetTester tester) async {
final int currentViewId = platformViewsRegistry.getNextPlatformViewId();
final FakeHtmlPlatformViewsController viewsController = FakeHtmlPlatformViewsController();
diff --git a/packages/flutter/test/widgets/image_filter_test.dart b/packages/flutter/test/widgets/image_filter_test.dart
index 6124566..29da67b 100644
--- a/packages/flutter/test/widgets/image_filter_test.dart
+++ b/packages/flutter/test/widgets/image_filter_test.dart
@@ -95,7 +95,7 @@
imageFilter: matrix,
child: MaterialApp(
title: 'Flutter Demo',
- theme: ThemeData(primarySwatch: Colors.blue),
+ theme: ThemeData(useMaterial3: false, primarySwatch: Colors.blue),
home: Scaffold(
appBar: AppBar(
title: const Text('Matrix ImageFilter Test'),
@@ -132,7 +132,7 @@
imageFilter: matrixFilter,
child: MaterialApp(
title: 'Flutter Demo',
- theme: ThemeData(primarySwatch: Colors.blue),
+ theme: ThemeData(useMaterial3: false, primarySwatch: Colors.blue),
home: Scaffold(
appBar: AppBar(
title: const Text('Matrix ImageFilter Test'),
diff --git a/packages/flutter/test/widgets/list_view_viewporting_test.dart b/packages/flutter/test/widgets/list_view_viewporting_test.dart
index 277b20e..43739d6 100644
--- a/packages/flutter/test/widgets/list_view_viewporting_test.dart
+++ b/packages/flutter/test/widgets/list_view_viewporting_test.dart
@@ -231,7 +231,7 @@
testWidgets('ListView reinvoke builders', (WidgetTester tester) async {
late StateSetter setState;
- ThemeData themeData = ThemeData.light();
+ ThemeData themeData = ThemeData.light(useMaterial3: false);
Widget itemBuilder(BuildContext context, int index) {
return Container(
@@ -263,7 +263,7 @@
expect(widget.color, equals(Colors.blue));
setState(() {
- themeData = ThemeData(primarySwatch: Colors.green);
+ themeData = ThemeData(primarySwatch: Colors.green, useMaterial3: false);
});
await tester.pump();
diff --git a/packages/flutter/test/widgets/live_text_utils.dart b/packages/flutter/test/widgets/live_text_utils.dart
new file mode 100644
index 0000000..5e7b3c0
--- /dev/null
+++ b/packages/flutter/test/widgets/live_text_utils.dart
@@ -0,0 +1,40 @@
+// Copyright 2014 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'package:flutter/services.dart';
+import 'package:flutter/widgets.dart';
+import 'package:flutter_test/flutter_test.dart';
+
+/// A mock class to control the return result of Live Text input functions.
+class LiveTextInputTester {
+ LiveTextInputTester() {
+ TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, _handler);
+ }
+
+ bool mockLiveTextInputEnabled = false;
+
+ Future<Object?> _handler(MethodCall methodCall) async {
+ // Need to set Clipboard.hasStrings method handler because when showing the tool bar,
+ // the Clipboard.hasStrings will also be invoked. If this isn't handled,
+ // an exception will be thrown.
+ if (methodCall.method == 'Clipboard.hasStrings') {
+ return <String, bool>{'value': true};
+ }
+ if (methodCall.method == 'LiveText.isLiveTextInputAvailable') {
+ return mockLiveTextInputEnabled;
+ }
+ return false;
+ }
+
+ void dispose() {
+ assert(TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.checkMockMessageHandler(SystemChannels.platform.name, _handler));
+ TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, null);
+ }
+}
+
+/// A function to find the live text button.
+Finder findLiveTextButton() => find.byWidgetPredicate((Widget widget) =>
+ widget is CustomPaint &&
+ '${widget.painter?.runtimeType}' == '_LiveTextIconPainter',
+);
diff --git a/packages/flutter/test/widgets/mark_needs_build_test.dart b/packages/flutter/test/widgets/mark_needs_build_test.dart
index dbe1d3c..9fa2d00 100644
--- a/packages/flutter/test/widgets/mark_needs_build_test.dart
+++ b/packages/flutter/test/widgets/mark_needs_build_test.dart
@@ -106,7 +106,7 @@
calledDuringBuild++;
});
return SizedBox.expand(
- child: Text(Directionality.of(context).toString()),
+ child: Text('${widget.value}: ${Directionality.of(context)}'),
);
}
}
diff --git a/packages/flutter/test/widgets/media_query_test.dart b/packages/flutter/test/widgets/media_query_test.dart
index 9516e35..135f284 100644
--- a/packages/flutter/test/widgets/media_query_test.dart
+++ b/packages/flutter/test/widgets/media_query_test.dart
@@ -154,6 +154,7 @@
expect(data.disableAnimations, false);
expect(data.boldText, false);
expect(data.highContrast, false);
+ expect(data.onOffSwitchLabels, false);
expect(data.platformBrightness, Brightness.light);
expect(data.gestureSettings.touchSlop, null);
expect(data.displayFeatures, isEmpty);
@@ -168,6 +169,7 @@
disableAnimations: true,
boldText: true,
highContrast: true,
+ onOffSwitchLabels: true,
alwaysUse24HourFormat: true,
navigationMode: NavigationMode.directional,
);
@@ -188,6 +190,7 @@
expect(data.disableAnimations, platformData.disableAnimations);
expect(data.boldText, platformData.boldText);
expect(data.highContrast, platformData.highContrast);
+ expect(data.onOffSwitchLabels, platformData.onOffSwitchLabels);
expect(data.alwaysUse24HourFormat, platformData.alwaysUse24HourFormat);
expect(data.navigationMode, platformData.navigationMode);
expect(data.gestureSettings, DeviceGestureSettings.fromView(tester.view));
@@ -217,6 +220,7 @@
expect(data.disableAnimations, tester.platformDispatcher.accessibilityFeatures.disableAnimations);
expect(data.boldText, tester.platformDispatcher.accessibilityFeatures.boldText);
expect(data.highContrast, tester.platformDispatcher.accessibilityFeatures.highContrast);
+ expect(data.onOffSwitchLabels, tester.platformDispatcher.accessibilityFeatures.onOffSwitchLabels);
expect(data.alwaysUse24HourFormat, tester.platformDispatcher.alwaysUse24HourFormat);
expect(data.navigationMode, NavigationMode.traditional);
expect(data.gestureSettings, DeviceGestureSettings.fromView(tester.view));
@@ -232,6 +236,7 @@
disableAnimations: true,
boldText: true,
highContrast: true,
+ onOffSwitchLabels: true,
alwaysUse24HourFormat: true,
navigationMode: NavigationMode.directional,
);
@@ -264,6 +269,7 @@
expect(data.disableAnimations, platformData.disableAnimations);
expect(data.boldText, platformData.boldText);
expect(data.highContrast, platformData.highContrast);
+ expect(data.onOffSwitchLabels, platformData.onOffSwitchLabels);
expect(data.alwaysUse24HourFormat, platformData.alwaysUse24HourFormat);
expect(data.navigationMode, platformData.navigationMode);
expect(data.gestureSettings, DeviceGestureSettings.fromView(tester.view));
@@ -311,6 +317,7 @@
expect(data.disableAnimations, tester.platformDispatcher.accessibilityFeatures.disableAnimations);
expect(data.boldText, tester.platformDispatcher.accessibilityFeatures.boldText);
expect(data.highContrast, tester.platformDispatcher.accessibilityFeatures.highContrast);
+ expect(data.onOffSwitchLabels, tester.platformDispatcher.accessibilityFeatures.onOffSwitchLabels);
expect(data.alwaysUse24HourFormat, tester.platformDispatcher.alwaysUse24HourFormat);
expect(data.navigationMode, NavigationMode.traditional);
expect(data.gestureSettings, DeviceGestureSettings.fromView(tester.view));
@@ -489,6 +496,7 @@
expect(copied.disableAnimations, data.disableAnimations);
expect(copied.boldText, data.boldText);
expect(copied.highContrast, data.highContrast);
+ expect(copied.onOffSwitchLabels, data.onOffSwitchLabels);
expect(copied.platformBrightness, data.platformBrightness);
expect(copied.gestureSettings, data.gestureSettings);
expect(copied.displayFeatures, data.displayFeatures);
@@ -528,6 +536,7 @@
disableAnimations: true,
boldText: true,
highContrast: true,
+ onOffSwitchLabels: true,
platformBrightness: Brightness.dark,
navigationMode: NavigationMode.directional,
gestureSettings: gestureSettings,
@@ -546,6 +555,7 @@
expect(copied.disableAnimations, true);
expect(copied.boldText, true);
expect(copied.highContrast, true);
+ expect(copied.onOffSwitchLabels, true);
expect(copied.platformBrightness, Brightness.dark);
expect(copied.navigationMode, NavigationMode.directional);
expect(copied.gestureSettings, gestureSettings);
@@ -583,6 +593,7 @@
disableAnimations: true,
boldText: true,
highContrast: true,
+ onOffSwitchLabels: true,
navigationMode: NavigationMode.directional,
displayFeatures: displayFeatures,
),
@@ -618,6 +629,7 @@
expect(unpadded.disableAnimations, true);
expect(unpadded.boldText, true);
expect(unpadded.highContrast, true);
+ expect(unpadded.onOffSwitchLabels, true);
expect(unpadded.navigationMode, NavigationMode.directional);
expect(unpadded.displayFeatures, displayFeatures);
});
@@ -653,6 +665,7 @@
disableAnimations: true,
boldText: true,
highContrast: true,
+ onOffSwitchLabels: true,
navigationMode: NavigationMode.directional,
displayFeatures: displayFeatures,
),
@@ -685,6 +698,7 @@
expect(unpadded.disableAnimations, true);
expect(unpadded.boldText, true);
expect(unpadded.highContrast, true);
+ expect(unpadded.onOffSwitchLabels, true);
expect(unpadded.navigationMode, NavigationMode.directional);
expect(unpadded.displayFeatures, displayFeatures);
});
@@ -720,6 +734,7 @@
disableAnimations: true,
boldText: true,
highContrast: true,
+ onOffSwitchLabels: true,
navigationMode: NavigationMode.directional,
displayFeatures: displayFeatures,
),
@@ -755,6 +770,7 @@
expect(unpadded.disableAnimations, true);
expect(unpadded.boldText, true);
expect(unpadded.highContrast, true);
+ expect(unpadded.onOffSwitchLabels, true);
expect(unpadded.navigationMode, NavigationMode.directional);
expect(unpadded.displayFeatures, displayFeatures);
});
@@ -790,6 +806,7 @@
disableAnimations: true,
boldText: true,
highContrast: true,
+ onOffSwitchLabels: true,
navigationMode: NavigationMode.directional,
displayFeatures: displayFeatures,
),
@@ -822,6 +839,7 @@
expect(unpadded.disableAnimations, true);
expect(unpadded.boldText, true);
expect(unpadded.highContrast, true);
+ expect(unpadded.onOffSwitchLabels, true);
expect(unpadded.navigationMode, NavigationMode.directional);
expect(unpadded.displayFeatures, displayFeatures);
});
@@ -857,6 +875,7 @@
disableAnimations: true,
boldText: true,
highContrast: true,
+ onOffSwitchLabels: true,
navigationMode: NavigationMode.directional,
displayFeatures: displayFeatures,
),
@@ -892,6 +911,7 @@
expect(unpadded.disableAnimations, true);
expect(unpadded.boldText, true);
expect(unpadded.highContrast, true);
+ expect(unpadded.onOffSwitchLabels, true);
expect(unpadded.navigationMode, NavigationMode.directional);
expect(unpadded.displayFeatures, displayFeatures);
});
@@ -927,6 +947,7 @@
disableAnimations: true,
boldText: true,
highContrast: true,
+ onOffSwitchLabels: true,
navigationMode: NavigationMode.directional,
displayFeatures: displayFeatures,
),
@@ -959,6 +980,7 @@
expect(unpadded.disableAnimations, true);
expect(unpadded.boldText, true);
expect(unpadded.highContrast, true);
+ expect(unpadded.onOffSwitchLabels, true);
expect(unpadded.navigationMode, NavigationMode.directional);
expect(unpadded.displayFeatures, displayFeatures);
});
@@ -1044,6 +1066,33 @@
expect(insideHighContrast, true);
});
+ testWidgets('MediaQuery.onOffSwitchLabelsOf', (WidgetTester tester) async {
+ late bool outsideOnOffSwitchLabels;
+ late bool insideOnOffSwitchLabels;
+
+ await tester.pumpWidget(
+ Builder(
+ builder: (BuildContext context) {
+ outsideOnOffSwitchLabels = MediaQuery.onOffSwitchLabelsOf(context);
+ return MediaQuery(
+ data: const MediaQueryData(
+ onOffSwitchLabels: true,
+ ),
+ child: Builder(
+ builder: (BuildContext context) {
+ insideOnOffSwitchLabels = MediaQuery.onOffSwitchLabelsOf(context);
+ return Container();
+ },
+ ),
+ );
+ },
+ ),
+ );
+
+ expect(outsideOnOffSwitchLabels, false);
+ expect(insideOnOffSwitchLabels, true);
+ });
+
testWidgets('MediaQuery.boldTextOf', (WidgetTester tester) async {
late bool outsideBoldTextOverride;
late bool insideBoldTextOverride;
@@ -1171,6 +1220,7 @@
disableAnimations: true,
boldText: true,
highContrast: true,
+ onOffSwitchLabels: true,
displayFeatures: displayFeatures,
),
child: Builder(
@@ -1201,6 +1251,7 @@
expect(subScreenMediaQuery.disableAnimations, true);
expect(subScreenMediaQuery.boldText, true);
expect(subScreenMediaQuery.highContrast, true);
+ expect(subScreenMediaQuery.onOffSwitchLabels, true);
expect(subScreenMediaQuery.displayFeatures, isEmpty);
});
@@ -1244,6 +1295,7 @@
disableAnimations: true,
boldText: true,
highContrast: true,
+ onOffSwitchLabels: true,
displayFeatures: displayFeatures,
),
child: Builder(
@@ -1283,6 +1335,7 @@
expect(subScreenMediaQuery.disableAnimations, true);
expect(subScreenMediaQuery.boldText, true);
expect(subScreenMediaQuery.highContrast, true);
+ expect(subScreenMediaQuery.onOffSwitchLabels, true);
expect(subScreenMediaQuery.displayFeatures, <DisplayFeature>[cutoutDisplayFeature]);
});
@@ -1453,6 +1506,8 @@
const _MediaQueryAspectCase(MediaQuery.maybeInvertColorsOf, MediaQueryData(invertColors: true)),
const _MediaQueryAspectCase(MediaQuery.highContrastOf, MediaQueryData(highContrast: true)),
const _MediaQueryAspectCase(MediaQuery.maybeHighContrastOf, MediaQueryData(highContrast: true)),
+ const _MediaQueryAspectCase(MediaQuery.onOffSwitchLabelsOf, MediaQueryData(onOffSwitchLabels: true)),
+ const _MediaQueryAspectCase(MediaQuery.maybeOnOffSwitchLabelsOf, MediaQueryData(onOffSwitchLabels: true)),
const _MediaQueryAspectCase(MediaQuery.disableAnimationsOf, MediaQueryData(disableAnimations: true)),
const _MediaQueryAspectCase(MediaQuery.maybeDisableAnimationsOf, MediaQueryData(disableAnimations: true)),
const _MediaQueryAspectCase(MediaQuery.boldTextOf, MediaQueryData(boldText: true)),
diff --git a/packages/flutter/test/widgets/nested_scroll_view_test.dart b/packages/flutter/test/widgets/nested_scroll_view_test.dart
index 695d4c0..c4b6e27 100644
--- a/packages/flutter/test/widgets/nested_scroll_view_test.dart
+++ b/packages/flutter/test/widgets/nested_scroll_view_test.dart
@@ -32,17 +32,8 @@
Key? key,
bool expanded = true,
}) {
- return Localizations(
- locale: const Locale('en', 'US'),
- delegates: const <LocalizationsDelegate<dynamic>>[
- DefaultMaterialLocalizations.delegate,
- DefaultWidgetsLocalizations.delegate,
- ],
- child: Directionality(
- textDirection: TextDirection.ltr,
- child: MediaQuery(
- data: const MediaQueryData(),
- child: Scaffold(
+ return MaterialApp(
+ home: Scaffold(
drawerDragStartBehavior: DragStartBehavior.down,
body: DefaultTabController(
length: 4,
@@ -114,8 +105,6 @@
),
),
),
- ),
- ),
);
}
@@ -577,7 +566,7 @@
const List<String> tabs = <String>['Hello', 'World'];
int buildCount = 0;
await tester.pumpWidget(
- MaterialApp(home: Material(child:
+ MaterialApp(theme: ThemeData(useMaterial3: false), home: Material(child:
// THE FOLLOWING SECTION IS FROM THE NestedScrollView DOCUMENTATION
// (EXCEPT FOR THE CHANGES TO THE buildCount COUNTER)
DefaultTabController(
@@ -2274,6 +2263,7 @@
// Regression tests for https://github.com/flutter/flutter/issues/17096
Widget buildBallisticTest(ScrollController controller) {
return MaterialApp(
+ theme: ThemeData(useMaterial3: false),
home: Scaffold(
body: NestedScrollView(
controller: controller,
diff --git a/packages/flutter/test/widgets/opacity_test.dart b/packages/flutter/test/widgets/opacity_test.dart
index 73f97f3..804f35a 100644
--- a/packages/flutter/test/widgets/opacity_test.dart
+++ b/packages/flutter/test/widgets/opacity_test.dart
@@ -155,6 +155,7 @@
testWidgets('offset is correctly handled in Opacity', (WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
+ theme: ThemeData(useMaterial3: false),
home: Scaffold(
body: SingleChildScrollView(
child: RepaintBoundary(
diff --git a/packages/flutter/test/widgets/overlay_portal_test.dart b/packages/flutter/test/widgets/overlay_portal_test.dart
index 85b1a71..1d90ecf 100644
--- a/packages/flutter/test/widgets/overlay_portal_test.dart
+++ b/packages/flutter/test/widgets/overlay_portal_test.dart
@@ -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 'package:flutter/foundation.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
@@ -29,7 +28,7 @@
void rebuildLayoutBuilderSubtree(RenderBox descendant) {
assert(descendant is! RenderConstrainedLayoutBuilder<BoxConstraints, RenderBox>);
- AbstractNode? node = descendant.parent;
+ RenderObject? node = descendant.parent;
while (node != null) {
if (node is! RenderConstrainedLayoutBuilder<BoxConstraints, RenderBox>) {
node = node.parent;
@@ -74,7 +73,7 @@
if (node.runtimeType.toString() == '_RenderTheater') {
results.add(node);
}
- final AbstractNode? parent = node.parent;
+ final RenderObject? parent = node.parent;
node = parent is RenderObject? parent : null;
}
return results;
@@ -165,6 +164,97 @@
await tester.pumpWidget(SizedBox(child: widget));
});
+ testWidgets('Safe to hide overlay child and remove OverlayPortal in the same frame', (WidgetTester tester) async {
+ // Regression test for https://github.com/flutter/flutter/issues/129025.
+ final Widget widget = Directionality(
+ key: GlobalKey(debugLabel: 'key'),
+ textDirection: TextDirection.ltr,
+ child: Overlay(
+ initialEntries: <OverlayEntry>[
+ OverlayEntry(
+ builder: (BuildContext context) {
+ return OverlayPortal(
+ controller: controller1,
+ overlayChildBuilder: (BuildContext context) => const SizedBox(),
+ child: const SizedBox(),
+ );
+ },
+ ),
+ ],
+ ),
+ );
+
+ controller1.show();
+ await tester.pumpWidget(widget);
+
+ controller1.hide();
+ await tester.pumpWidget(const SizedBox());
+ expect(tester.takeException(), isNull);
+ });
+
+ testWidgets('Safe to hide overlay child and reparent OverlayPortal in the same frame', (WidgetTester tester) async {
+ final OverlayPortal overlayPortal = OverlayPortal(
+ key: GlobalKey(debugLabel: 'key'),
+ controller: controller1,
+ overlayChildBuilder: (BuildContext context) => const SizedBox(),
+ child: const SizedBox(),
+ );
+
+ List<Widget> children = <Widget>[ const SizedBox(), overlayPortal ];
+
+ late StateSetter setState;
+ final Widget widget = Directionality(
+ textDirection: TextDirection.ltr,
+ child: Overlay(
+ initialEntries: <OverlayEntry>[
+ OverlayStatefulEntry(
+ builder: (BuildContext context, StateSetter setter) {
+ setState = setter;
+ return Column(children: children);
+ },
+ ),
+ ],
+ ),
+ );
+
+ controller1.show();
+ await tester.pumpWidget(widget);
+
+ controller1.hide();
+ setState(() {
+ children = <Widget>[ overlayPortal, const SizedBox() ];
+ });
+ await tester.pumpWidget(widget);
+ expect(tester.takeException(), isNull);
+ });
+
+ testWidgets('Safe to hide overlay child and reparent OverlayPortal in the same frame 2', (WidgetTester tester) async {
+ final Widget widget = Directionality(
+ key: GlobalKey(debugLabel: 'key'),
+ textDirection: TextDirection.ltr,
+ child: Overlay(
+ initialEntries: <OverlayEntry>[
+ OverlayEntry(
+ builder: (BuildContext context) {
+ return OverlayPortal(
+ controller: controller1,
+ overlayChildBuilder: (BuildContext context) => const SizedBox(),
+ child: const SizedBox(),
+ );
+ },
+ ),
+ ],
+ ),
+ );
+
+ controller1.show();
+ await tester.pumpWidget(widget);
+
+ controller1.hide();
+ await tester.pumpWidget(SizedBox(child: widget));
+ expect(tester.takeException(), isNull);
+ });
+
testWidgets('Throws when the same controller is attached to multiple OverlayPortal', (WidgetTester tester) async {
final OverlayPortalController controller = OverlayPortalController(debugLabel: 'local controller');
final Widget widget = Directionality(
@@ -1408,6 +1498,64 @@
expect(counter2.layoutCount, 3);
});
});
+
+ testWidgets('Safe to move the overlay child to a different Overlay and remove the old Overlay', (WidgetTester tester) async {
+ controller1.show();
+ final GlobalKey key = GlobalKey(debugLabel: 'key');
+ final GlobalKey oldOverlayKey = GlobalKey(debugLabel: 'old overlay');
+ final GlobalKey newOverlayKey = GlobalKey(debugLabel: 'new overlay');
+ final GlobalKey overlayChildKey = GlobalKey(debugLabel: 'overlay child key');
+ await tester.pumpWidget(
+ Directionality(
+ textDirection: TextDirection.ltr,
+ child: Overlay(
+ key: oldOverlayKey,
+ initialEntries: <OverlayEntry>[
+ OverlayEntry(
+ builder: (BuildContext context) {
+ return OverlayPortal(
+ key: key,
+ controller: controller1,
+ overlayChildBuilder: (BuildContext context) => SizedBox(key: overlayChildKey),
+ child: const SizedBox(),
+ );
+ },
+ ),
+ ],
+ ),
+ ),
+ );
+
+ expect(find.byKey(overlayChildKey), findsOneWidget);
+ expect(find.byKey(newOverlayKey), findsNothing);
+ expect(find.byKey(oldOverlayKey), findsOneWidget);
+
+ await tester.pumpWidget(
+ Directionality(
+ textDirection: TextDirection.ltr,
+ child: Overlay(
+ key: newOverlayKey,
+ initialEntries: <OverlayEntry>[
+ OverlayEntry(
+ builder: (BuildContext context) {
+ return OverlayPortal(
+ key: key,
+ controller: controller1,
+ overlayChildBuilder: (BuildContext context) => SizedBox(key: overlayChildKey),
+ child: const SizedBox(),
+ );
+ },
+ ),
+ ],
+ ),
+ ),
+ );
+
+ expect(tester.takeException(), isNull);
+ expect(find.byKey(overlayChildKey), findsOneWidget);
+ expect(find.byKey(newOverlayKey), findsOneWidget);
+ expect(find.byKey(oldOverlayKey), findsNothing);
+ });
});
group('Paint order', () {
@@ -1525,14 +1673,14 @@
final List<RenderObject> childrenVisited = <RenderObject>[];
theater.visitChildren(childrenVisited.add);
expect(childrenVisited.length, 3);
- expect(childrenVisited, containsAllInOrder(<AbstractNode>[child1Box.parent!, child2Box.parent!]));
+ expect(childrenVisited, containsAllInOrder(<RenderObject>[child1Box.parent!, child2Box.parent!]));
childrenVisited.clear();
setState(() { reparented = true; });
await tester.pump();
theater.visitChildren(childrenVisited.add);
// The child list stays the same.
- expect(childrenVisited, containsAllInOrder(<AbstractNode>[child1Box.parent!, child2Box.parent!]));
+ expect(childrenVisited, containsAllInOrder(<RenderObject>[child1Box.parent!, child2Box.parent!]));
});
});
}
diff --git a/packages/flutter/test/widgets/page_route_builder_test.dart b/packages/flutter/test/widgets/page_route_builder_test.dart
index 6bf6b7c..3e6090f 100644
--- a/packages/flutter/test/widgets/page_route_builder_test.dart
+++ b/packages/flutter/test/widgets/page_route_builder_test.dart
@@ -11,13 +11,16 @@
import 'package:flutter_test/flutter_test.dart';
class TestPage extends StatelessWidget {
- const TestPage({super.key});
+ const TestPage({ super.key, this.useMaterial3 });
+
+ final bool? useMaterial3;
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Test',
theme: ThemeData(
+ useMaterial3: useMaterial3,
primarySwatch: Colors.blue,
),
home: const HomePage(),
@@ -90,13 +93,23 @@
}
void main() {
- testWidgets('Barriers show when using PageRouteBuilder', (WidgetTester tester) async {
- await tester.pumpWidget(const TestPage());
+ testWidgets('Material2 - Barriers show when using PageRouteBuilder', (WidgetTester tester) async {
+ await tester.pumpWidget(const TestPage(useMaterial3: false));
await tester.tap(find.byType(FloatingActionButton));
await tester.pumpAndSettle();
await expectLater(
find.byType(TestPage),
- matchesGoldenFile('page_route_builder.barrier.png'),
+ matchesGoldenFile('m2_page_route_builder.barrier.png'),
+ );
+ });
+
+ testWidgets('Material3 - Barriers show when using PageRouteBuilder', (WidgetTester tester) async {
+ await tester.pumpWidget(const TestPage(useMaterial3: true));
+ await tester.tap(find.byType(FloatingActionButton));
+ await tester.pumpAndSettle();
+ await expectLater(
+ find.byType(TestPage),
+ matchesGoldenFile('m3_page_route_builder.barrier.png'),
);
});
}
diff --git a/packages/flutter/test/widgets/physical_model_test.dart b/packages/flutter/test/widgets/physical_model_test.dart
index c5ac33c..7d3146b 100644
--- a/packages/flutter/test/widgets/physical_model_test.dart
+++ b/packages/flutter/test/widgets/physical_model_test.dart
@@ -47,20 +47,23 @@
testWidgets('PhysicalModel - clips when overflows and elevation is 0', (WidgetTester tester) async {
const Key key = Key('test');
await tester.pumpWidget(
- const MediaQuery(
- key: key,
- data: MediaQueryData(),
- child: Directionality(
- textDirection: TextDirection.ltr,
- child: Padding(
- padding: EdgeInsets.all(50),
- child: Row(
- children: <Widget>[
- Material(child: Text('A long long long long long long long string')),
- Material(child: Text('A long long long long long long long string')),
- Material(child: Text('A long long long long long long long string')),
- Material(child: Text('A long long long long long long long string')),
- ],
+ Theme(
+ data: ThemeData(useMaterial3: false),
+ child: const MediaQuery(
+ key: key,
+ data: MediaQueryData(),
+ child: Directionality(
+ textDirection: TextDirection.ltr,
+ child: Padding(
+ padding: EdgeInsets.all(50),
+ child: Row(
+ children: <Widget>[
+ Material(child: Text('A long long long long long long long string')),
+ Material(child: Text('A long long long long long long long string')),
+ Material(child: Text('A long long long long long long long string')),
+ Material(child: Text('A long long long long long long long string')),
+ ],
+ ),
),
),
),
diff --git a/packages/flutter/test/widgets/platform_view_test.dart b/packages/flutter/test/widgets/platform_view_test.dart
index 1016909..7b4bc72 100644
--- a/packages/flutter/test/widgets/platform_view_test.dart
+++ b/packages/flutter/test/widgets/platform_view_test.dart
@@ -3168,4 +3168,28 @@
expect(controller.dispatchedPointerEvents, hasLength(1));
expect(controller.dispatchedPointerEvents[0], isA<PointerHoverEvent>());
});
+
+ testWidgets('HtmlElementView can be instantiated', (WidgetTester tester) async {
+ late final Widget htmlElementView;
+ expect(() {
+ htmlElementView = const HtmlElementView(viewType: 'webview');
+ }, returnsNormally);
+
+ await tester.pumpWidget(
+ Center(
+ child: SizedBox(
+ width: 100,
+ height: 100,
+ child: htmlElementView,
+ ),
+ )
+ );
+ await tester.pumpAndSettle();
+
+ // This file runs on non-web platforms, so we expect `HtmlElementView` to
+ // fail.
+ final dynamic exception = tester.takeException();
+ expect(exception, isAssertionError);
+ expect(exception.toString(), contains('HtmlElementView is only available on Flutter Web'));
+ });
}
diff --git a/packages/flutter/test/widgets/render_object_element_test.dart b/packages/flutter/test/widgets/render_object_element_test.dart
index b3accf9..a485d3f 100644
--- a/packages/flutter/test/widgets/render_object_element_test.dart
+++ b/packages/flutter/test/widgets/render_object_element_test.dart
@@ -137,8 +137,8 @@
}
class RenderSwapper extends RenderBox {
- RenderBox? _stable;
RenderBox? get stable => _stable;
+ RenderBox? _stable;
set stable(RenderBox? child) {
if (child == _stable) {
return;
@@ -153,8 +153,8 @@
}
bool? _swapperIsOnTop;
- RenderBox? _swapper;
RenderBox? get swapper => _swapper;
+ RenderBox? _swapper;
void setSwapper(RenderBox? child, bool isOnTop) {
if (isOnTop != _swapperIsOnTop) {
_swapperIsOnTop = isOnTop;
@@ -174,11 +174,11 @@
@override
void visitChildren(RenderObjectVisitor visitor) {
- if (_stable != null) {
- visitor(_stable!);
+ if (stable != null) {
+ visitor(stable!);
}
- if (_swapper != null) {
- visitor(_swapper!);
+ if (swapper != null) {
+ visitor(swapper!);
}
}
@@ -210,14 +210,14 @@
minHeight: constraints.minHeight / 2,
maxHeight: constraints.maxHeight / 2,
);
- if (_stable != null) {
- final BoxParentData stableParentData = _stable!.parentData! as BoxParentData;
- _stable!.layout(childConstraints);
+ if (stable != null) {
+ final BoxParentData stableParentData = stable!.parentData! as BoxParentData;
+ stable!.layout(childConstraints);
stableParentData.offset = _swapperIsOnTop! ? bottomOffset : topOffset;
}
- if (_swapper != null) {
- final BoxParentData swapperParentData = _swapper!.parentData! as BoxParentData;
- _swapper!.layout(childConstraints);
+ if (swapper != null) {
+ final BoxParentData swapperParentData = swapper!.parentData! as BoxParentData;
+ swapper!.layout(childConstraints);
swapperParentData.offset = _swapperIsOnTop! ? topOffset : bottomOffset;
}
}
diff --git a/packages/flutter/test/widgets/reparent_state_harder_test.dart b/packages/flutter/test/widgets/reparent_state_harder_test.dart
index f022a82..d7029bb 100644
--- a/packages/flutter/test/widgets/reparent_state_harder_test.dart
+++ b/packages/flutter/test/widgets/reparent_state_harder_test.dart
@@ -63,10 +63,8 @@
class RekeyableDummyStatefulWidgetWrapper extends StatefulWidget {
const RekeyableDummyStatefulWidgetWrapper({
super.key,
- this.child,
required this.initialKey,
});
- final Widget? child;
final GlobalKey initialKey;
@override
RekeyableDummyStatefulWidgetWrapperState createState() => RekeyableDummyStatefulWidgetWrapperState();
diff --git a/packages/flutter/test/widgets/router_test.dart b/packages/flutter/test/widgets/router_test.dart
index be0b375..f07d592 100644
--- a/packages/flutter/test/widgets/router_test.dart
+++ b/packages/flutter/test/widgets/router_test.dart
@@ -1610,10 +1610,6 @@
RouteInformation get routeInformation => _routeInformation;
late RouteInformation _routeInformation;
- set routeInformation(RouteInformation newValue) {
- _routeInformation = newValue;
- notifyListeners();
- }
SimpleRouterDelegateBuilder builder;
SimpleNavigatorRouterDelegatePopPage<void> onPopPage;
@@ -1711,10 +1707,6 @@
RouteInformation? get routeInformation => _routeInformation;
RouteInformation? _routeInformation;
- set routeInformation(RouteInformation? newValue) {
- _routeInformation = newValue;
- notifyListeners();
- }
SimpleRouterDelegateBuilder builder;
late Future<void> setNewRouteFuture;
diff --git a/packages/flutter/test/widgets/scrollable_helpers_test.dart b/packages/flutter/test/widgets/scrollable_helpers_test.dart
index 9909c57..17b623d 100644
--- a/packages/flutter/test/widgets/scrollable_helpers_test.dart
+++ b/packages/flutter/test/widgets/scrollable_helpers_test.dart
@@ -549,4 +549,33 @@
equals(const Rect.fromLTRB(0.0, 100.0, 800.0, 200.0)),
);
}, variant: KeySimulatorTransitModeVariant.all());
+
+ testWidgets('Can scroll using intents only', (WidgetTester tester) async {
+ await tester.pumpWidget(
+ MaterialApp(
+ home: ListView(
+ children: const <Widget>[
+ SizedBox(height: 600.0, child: Text('The cow as white as milk')),
+ SizedBox(height: 600.0, child: Text('The cape as red as blood')),
+ SizedBox(height: 600.0, child: Text('The hair as yellow as corn')),
+ ],
+ ),
+ ),
+ );
+ expect(find.text('The cow as white as milk'), findsOneWidget);
+ expect(find.text('The cape as red as blood'), findsNothing);
+ expect(find.text('The hair as yellow as corn'), findsNothing);
+ Actions.invoke(tester.element(find.byType(SliverList)), const ScrollIntent(direction: AxisDirection.down, type: ScrollIncrementType.page));
+ await tester.pump(); // start scroll
+ await tester.pump(const Duration(milliseconds: 1000)); // end scroll
+ expect(find.text('The cow as white as milk'), findsOneWidget);
+ expect(find.text('The cape as red as blood'), findsOneWidget);
+ expect(find.text('The hair as yellow as corn'), findsNothing);
+ Actions.invoke(tester.element(find.byType(SliverList)), const ScrollIntent(direction: AxisDirection.down, type: ScrollIncrementType.page));
+ await tester.pump(); // start scroll
+ await tester.pump(const Duration(milliseconds: 1000)); // end scroll
+ expect(find.text('The cow as white as milk'), findsNothing);
+ expect(find.text('The cape as red as blood'), findsOneWidget);
+ expect(find.text('The hair as yellow as corn'), findsOneWidget);
+ });
}
diff --git a/packages/flutter/test/widgets/scrollable_selection_test.dart b/packages/flutter/test/widgets/scrollable_selection_test.dart
index a6b3779..54a07e2 100644
--- a/packages/flutter/test/widgets/scrollable_selection_test.dart
+++ b/packages/flutter/test/widgets/scrollable_selection_test.dart
@@ -158,6 +158,7 @@
testWidgets('select to scroll works for small scrollable', (WidgetTester tester) async {
final ScrollController controller = ScrollController();
await tester.pumpWidget(MaterialApp(
+ theme: ThemeData(useMaterial3: false),
home: SelectionArea(
selectionControls: materialTextSelectionControls,
child: Scaffold(
diff --git a/packages/flutter/test/widgets/scrollable_test.dart b/packages/flutter/test/widgets/scrollable_test.dart
index 366e058..01ba9bc 100644
--- a/packages/flutter/test/widgets/scrollable_test.dart
+++ b/packages/flutter/test/widgets/scrollable_test.dart
@@ -947,6 +947,7 @@
final ScrollController outerController = ScrollController();
final ScrollController innerController = ScrollController();
await tester.pumpWidget(MaterialApp(
+ theme: ThemeData(useMaterial3: false),
home: Scaffold(
body: SingleChildScrollView(
controller: outerController,
diff --git a/packages/flutter/test/widgets/selectable_region_context_menu_test.dart b/packages/flutter/test/widgets/selectable_region_context_menu_test.dart
index e49aa01..5ec1891 100644
--- a/packages/flutter/test/widgets/selectable_region_context_menu_test.dart
+++ b/packages/flutter/test/widgets/selectable_region_context_menu_test.dart
@@ -5,27 +5,22 @@
@TestOn('browser') // This file contains web-only library.
library;
-import 'dart:js_interop';
-
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:web/web.dart' as web;
-extension on JSString {
- external JSBoolean includes(JSString searchString);
-}
extension on web.HTMLCollection {
- Iterable<web.Element> get iterable => _genIterable(length, (JSNumber i) => item(i));
+ Iterable<web.Element> get iterable => _genIterable(this);
}
extension on web.CSSRuleList {
- Iterable<web.CSSRule> get iterable => _genIterable(length, (JSNumber i) => item(i));
+ Iterable<web.CSSRule> get iterable => _genIterable(this);
}
-typedef ItemGetter<T> = T? Function(JSNumber index);
-Iterable<T> _genIterable<T>(JSNumber length, ItemGetter<T> getItem) {
- return Iterable<T>.generate(length.toDart.toInt(), (int index) => getItem(index.toJS)!);
+Iterable<T> _genIterable<T>(dynamic jsCollection) {
+ // ignore: avoid_dynamic_calls
+ return Iterable<T>.generate(jsCollection.length as int, (int index) => jsCollection.item(index) as T,);
}
void main() {
@@ -42,20 +37,20 @@
test('DOM element is set up correctly', () async {
expect(element, isNotNull);
- expect(element!.style.width, '100%'.toJS);
- expect(element!.style.height, '100%'.toJS);
- expect(element!.classList.length, 1.toJS);
- final JSString className = element!.className;
+ expect(element!.style.width, '100%');
+ expect(element!.style.height, '100%');
+ expect(element!.classList.length, 1);
+ final String className = element!.className;
expect(web.document.head!.children.iterable, isNotEmpty);
bool foundStyle = false;
for (final web.Element element in web.document.head!.children.iterable) {
- if (element.tagName != 'STYLE'.toJS) {
+ if (element.tagName != 'STYLE') {
continue;
}
final web.CSSRuleList? rules = (element as web.HTMLStyleElement).sheet?.rules;
if (rules != null) {
- foundStyle = rules.iterable.any((web.CSSRule rule) => rule.cssText.includes(className).toDart);
+ foundStyle = rules.iterable.any((web.CSSRule rule) => rule.cssText.contains(className));
}
if (foundStyle) {
break;
@@ -84,11 +79,11 @@
// Dispatch right click.
element!.dispatchEvent(
web.MouseEvent(
- 'mousedown'.toJS,
+ 'mousedown',
web.MouseEventInit(
- button: 2.toJS,
- clientX: 200.toJS,
- clientY: 300.toJS,
+ button: 2,
+ clientX: 200,
+ clientY: 300,
),
),
);
@@ -163,8 +158,7 @@
}
@override
- SelectionGeometry get value => _value;
- SelectionGeometry _value = const SelectionGeometry(
+ final SelectionGeometry value = const SelectionGeometry(
hasContent: true,
status: SelectionStatus.uncollapsed,
startSelectionPoint: SelectionPoint(
@@ -178,15 +172,6 @@
handleType: TextSelectionHandleType.left,
),
);
- set value(SelectionGeometry other) {
- if (other == _value) {
- return;
- }
- _value = other;
- for (final VoidCallback callback in listeners) {
- callback();
- }
- }
@override
void pushHandleLayers(LayerLink? startHandle, LayerLink? endHandle) { }
diff --git a/packages/flutter/test/widgets/selectable_region_test.dart b/packages/flutter/test/widgets/selectable_region_test.dart
index e9297b5..7d9fbd1 100644
--- a/packages/flutter/test/widgets/selectable_region_test.dart
+++ b/packages/flutter/test/widgets/selectable_region_test.dart
@@ -310,6 +310,82 @@
expect(edgeEvent.globalPosition, const Offset(200.0, 50.0));
});
+ testWidgets(
+ 'touch long press cancel does not send ClearSelectionEvent',
+ (WidgetTester tester) async {
+ final UniqueKey spy = UniqueKey();
+ await tester.pumpWidget(
+ MaterialApp(
+ home: SelectableRegion(
+ focusNode: FocusNode(),
+ selectionControls: materialTextSelectionControls,
+ child: SelectionSpy(key: spy),
+ ),
+ ),
+ );
+ await tester.pumpAndSettle();
+
+ final RenderSelectionSpy renderSelectionSpy =
+ tester.renderObject<RenderSelectionSpy>(find.byKey(spy));
+ renderSelectionSpy.events.clear();
+ final TestGesture gesture =
+ await tester.startGesture(const Offset(200.0, 200.0));
+
+ addTearDown(gesture.removePointer);
+
+ await tester.pump(const Duration(milliseconds: 500));
+ await gesture.cancel();
+ expect(
+ renderSelectionSpy.events.any((SelectionEvent element) => element is ClearSelectionEvent),
+ isFalse,
+ );
+ },
+ );
+
+ testWidgets(
+ 'scrolling after the selection does not send ClearSelectionEvent',
+ (WidgetTester tester) async {
+ // Regression test for https://github.com/flutter/flutter/issues/128765
+ final UniqueKey spy = UniqueKey();
+ await tester.pumpWidget(
+ MaterialApp(
+ home: SizedBox(
+ height: 750,
+ child: SingleChildScrollView(
+ child: SizedBox(
+ height: 2000,
+ child: SelectableRegion(
+ focusNode: FocusNode(),
+ selectionControls: materialTextSelectionControls,
+ child: SelectionSpy(key: spy),
+ ),
+ ),
+ ),
+ ),
+ ),
+ );
+ await tester.pumpAndSettle();
+
+ final RenderSelectionSpy renderSelectionSpy = tester.renderObject<RenderSelectionSpy>(find.byKey(spy));
+ renderSelectionSpy.events.clear();
+ final TestGesture selectGesture = await tester.startGesture(const Offset(200.0, 200.0));
+ addTearDown(selectGesture.removePointer);
+ await tester.pump(const Duration(milliseconds: 500));
+ await selectGesture.up();
+ expect(renderSelectionSpy.events.length, 1);
+ expect(renderSelectionSpy.events[0], isA<SelectWordSelectionEvent>());
+
+ renderSelectionSpy.events.clear();
+ final TestGesture scrollGesture =
+ await tester.startGesture(const Offset(250.0, 850.0));
+ await tester.pump(const Duration(milliseconds: 500));
+ await scrollGesture.moveTo(Offset.zero);
+ await scrollGesture.up();
+ await tester.pumpAndSettle();
+ expect(renderSelectionSpy.events.length, 0);
+ },
+ );
+
testWidgets('mouse long press does not send select-word event', (WidgetTester tester) async {
final UniqueKey spy = UniqueKey();
await tester.pumpWidget(
@@ -560,6 +636,403 @@
await gesture.up();
});
+ testWidgets(
+ 'right-click mouse can select word at position on Apple platforms',
+ (WidgetTester tester) async {
+ Set<ContextMenuButtonType> buttonTypes = <ContextMenuButtonType>{};
+ final UniqueKey toolbarKey = UniqueKey();
+ await tester.pumpWidget(
+ MaterialApp(
+ home: SelectableRegion(
+ focusNode: FocusNode(),
+ selectionControls: materialTextSelectionHandleControls,
+ contextMenuBuilder: (
+ BuildContext context,
+ SelectableRegionState selectableRegionState,
+ ) {
+ buttonTypes = selectableRegionState.contextMenuButtonItems
+ .map((ContextMenuButtonItem buttonItem) => buttonItem.type)
+ .toSet();
+ return SizedBox.shrink(key: toolbarKey);
+ },
+ child: const Center(
+ child: Text('How are you'),
+ ),
+ ),
+ ),
+ );
+
+ expect(buttonTypes.isEmpty, true);
+ expect(find.byKey(toolbarKey), findsNothing);
+
+ final RenderParagraph paragraph = tester.renderObject<RenderParagraph>(find.descendant(of: find.text('How are you'), matching: find.byType(RichText)));
+ final TestGesture gesture = await tester.startGesture(textOffsetToPosition(paragraph, 2), kind: PointerDeviceKind.mouse, buttons: kSecondaryMouseButton);
+ addTearDown(gesture.removePointer);
+ await tester.pump();
+ expect(paragraph.selections[0], const TextSelection(baseOffset: 0, extentOffset: 3));
+
+ await gesture.up();
+ await tester.pump();
+
+ expect(buttonTypes, contains(ContextMenuButtonType.copy));
+ expect(buttonTypes, contains(ContextMenuButtonType.selectAll));
+ expect(find.byKey(toolbarKey), findsOneWidget);
+
+ await gesture.down(textOffsetToPosition(paragraph, 6));
+ await tester.pump();
+ expect(paragraph.selections[0], const TextSelection(baseOffset: 4, extentOffset: 7));
+
+ await gesture.up();
+ await tester.pump();
+
+ expect(buttonTypes, contains(ContextMenuButtonType.copy));
+ expect(buttonTypes, contains(ContextMenuButtonType.selectAll));
+ expect(find.byKey(toolbarKey), findsOneWidget);
+
+ await gesture.down(textOffsetToPosition(paragraph, 9));
+ await tester.pump();
+ expect(paragraph.selections[0], const TextSelection(baseOffset: 8, extentOffset: 11));
+
+ await gesture.up();
+ await tester.pump();
+
+ expect(buttonTypes, contains(ContextMenuButtonType.copy));
+ expect(buttonTypes, contains(ContextMenuButtonType.selectAll));
+ expect(find.byKey(toolbarKey), findsOneWidget);
+
+ // Clear selection.
+ await tester.tapAt(textOffsetToPosition(paragraph, 1));
+ await tester.pump();
+ expect(paragraph.selections.isEmpty, true);
+ expect(find.byKey(toolbarKey), findsNothing);
+ },
+ variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }),
+ skip: kIsWeb, // [intended] Web uses its native context menu.
+ );
+
+ testWidgets(
+ 'right-click mouse at the same position as previous right-click toggles the context menu on macOS',
+ (WidgetTester tester) async {
+ Set<ContextMenuButtonType> buttonTypes = <ContextMenuButtonType>{};
+ final UniqueKey toolbarKey = UniqueKey();
+ await tester.pumpWidget(
+ MaterialApp(
+ home: SelectableRegion(
+ focusNode: FocusNode(),
+ selectionControls: materialTextSelectionHandleControls,
+ contextMenuBuilder: (
+ BuildContext context,
+ SelectableRegionState selectableRegionState,
+ ) {
+ buttonTypes = selectableRegionState.contextMenuButtonItems
+ .map((ContextMenuButtonItem buttonItem) => buttonItem.type)
+ .toSet();
+ return SizedBox.shrink(key: toolbarKey);
+ },
+ child: const Center(
+ child: Text('How are you'),
+ ),
+ ),
+ ),
+ );
+
+ expect(buttonTypes.isEmpty, true);
+ expect(find.byKey(toolbarKey), findsNothing);
+
+ final RenderParagraph paragraph = tester.renderObject<RenderParagraph>(find.descendant(of: find.text('How are you'), matching: find.byType(RichText)));
+ final TestGesture gesture = await tester.startGesture(textOffsetToPosition(paragraph, 2), kind: PointerDeviceKind.mouse, buttons: kSecondaryMouseButton);
+ addTearDown(gesture.removePointer);
+ await tester.pump();
+ expect(paragraph.selections[0], const TextSelection(baseOffset: 0, extentOffset: 3));
+
+ await gesture.up();
+ await tester.pump();
+
+ expect(buttonTypes, contains(ContextMenuButtonType.copy));
+ expect(buttonTypes, contains(ContextMenuButtonType.selectAll));
+ expect(find.byKey(toolbarKey), findsOneWidget);
+
+ await gesture.down(textOffsetToPosition(paragraph, 2));
+ await tester.pump();
+ expect(paragraph.selections[0], const TextSelection(baseOffset: 0, extentOffset: 3));
+
+ await gesture.up();
+ await tester.pump();
+
+ // Right-click at same position will toggle the context menu off.
+ expect(buttonTypes, contains(ContextMenuButtonType.copy));
+ expect(buttonTypes, contains(ContextMenuButtonType.selectAll));
+ expect(find.byKey(toolbarKey), findsNothing);
+
+ await gesture.down(textOffsetToPosition(paragraph, 9));
+ await tester.pump();
+ expect(paragraph.selections[0], const TextSelection(baseOffset: 8, extentOffset: 11));
+
+ await gesture.up();
+ await tester.pump();
+
+ expect(buttonTypes, contains(ContextMenuButtonType.copy));
+ expect(buttonTypes, contains(ContextMenuButtonType.selectAll));
+ expect(find.byKey(toolbarKey), findsOneWidget);
+
+ await gesture.down(textOffsetToPosition(paragraph, 9));
+ await tester.pump();
+ expect(paragraph.selections[0], const TextSelection(baseOffset: 8, extentOffset: 11));
+
+ await gesture.up();
+ await tester.pump();
+
+ // Right-click at same position will toggle the context menu off.
+ expect(buttonTypes, contains(ContextMenuButtonType.copy));
+ expect(buttonTypes, contains(ContextMenuButtonType.selectAll));
+ expect(find.byKey(toolbarKey), findsNothing);
+
+ await gesture.down(textOffsetToPosition(paragraph, 6));
+ await tester.pump();
+ expect(paragraph.selections[0], const TextSelection(baseOffset: 4, extentOffset: 7));
+
+ await gesture.up();
+ await tester.pump();
+
+ expect(buttonTypes, contains(ContextMenuButtonType.copy));
+ expect(buttonTypes, contains(ContextMenuButtonType.selectAll));
+ expect(find.byKey(toolbarKey), findsOneWidget);
+
+ // Clear selection.
+ await tester.tapAt(textOffsetToPosition(paragraph, 1));
+ await tester.pump();
+ expect(paragraph.selections.isEmpty, true);
+ expect(find.byKey(toolbarKey), findsNothing);
+ },
+ variant: TargetPlatformVariant.only(TargetPlatform.macOS),
+ skip: kIsWeb, // [intended] Web uses its native context menu.
+ );
+
+ testWidgets(
+ 'right-click mouse shows the context menu at position on Android, Fucshia, and Windows',
+ (WidgetTester tester) async {
+ Set<ContextMenuButtonType> buttonTypes = <ContextMenuButtonType>{};
+ final UniqueKey toolbarKey = UniqueKey();
+ await tester.pumpWidget(
+ MaterialApp(
+ home: SelectableRegion(
+ focusNode: FocusNode(),
+ selectionControls: materialTextSelectionHandleControls,
+ contextMenuBuilder: (
+ BuildContext context,
+ SelectableRegionState selectableRegionState,
+ ) {
+ buttonTypes = selectableRegionState.contextMenuButtonItems
+ .map((ContextMenuButtonItem buttonItem) => buttonItem.type)
+ .toSet();
+ return SizedBox.shrink(key: toolbarKey);
+ },
+ child: const Center(
+ child: Text('How are you'),
+ ),
+ ),
+ ),
+ );
+
+ expect(buttonTypes.isEmpty, true);
+ expect(find.byKey(toolbarKey), findsNothing);
+
+ final RenderParagraph paragraph = tester.renderObject<RenderParagraph>(find.descendant(of: find.text('How are you'), matching: find.byType(RichText)));
+ final TestGesture gesture = await tester.startGesture(textOffsetToPosition(paragraph, 2), kind: PointerDeviceKind.mouse, buttons: kSecondaryMouseButton);
+ addTearDown(gesture.removePointer);
+ await tester.pump();
+ // Selection is collapsed so none is reported.
+ expect(paragraph.selections.isEmpty, true);
+
+ await gesture.up();
+ await tester.pump();
+
+ expect(buttonTypes.length, 1);
+ expect(buttonTypes, contains(ContextMenuButtonType.selectAll));
+ expect(find.byKey(toolbarKey), findsOneWidget);
+
+ await gesture.down(textOffsetToPosition(paragraph, 6));
+ await tester.pump();
+ expect(paragraph.selections.isEmpty, true);
+
+ await gesture.up();
+ await tester.pump();
+
+ expect(buttonTypes.length, 1);
+ expect(buttonTypes, contains(ContextMenuButtonType.selectAll));
+ expect(find.byKey(toolbarKey), findsOneWidget);
+
+ await gesture.down(textOffsetToPosition(paragraph, 9));
+ await tester.pump();
+ expect(paragraph.selections.isEmpty, true);
+
+ await gesture.up();
+ await tester.pump();
+
+ expect(buttonTypes.length, 1);
+ expect(buttonTypes, contains(ContextMenuButtonType.selectAll));
+ expect(find.byKey(toolbarKey), findsOneWidget);
+
+ // Clear selection.
+ await tester.tapAt(textOffsetToPosition(paragraph, 1));
+ await tester.pump();
+ expect(paragraph.selections.isEmpty, true);
+ expect(find.byKey(toolbarKey), findsNothing);
+
+ // Create an uncollapsed selection by dragging.
+ final TestGesture dragGesture = await tester.startGesture(textOffsetToPosition(paragraph, 0), kind: PointerDeviceKind.mouse);
+ addTearDown(dragGesture.removePointer);
+ await tester.pump();
+ await dragGesture.moveTo(textOffsetToPosition(paragraph, 5));
+ await tester.pump();
+ expect(paragraph.selections[0], const TextSelection(baseOffset: 0, extentOffset: 5));
+ await dragGesture.up();
+ await tester.pump();
+
+ // Right click on previous selection should not collapse the selection.
+ await gesture.down(textOffsetToPosition(paragraph, 2));
+ await tester.pump();
+ await gesture.up();
+ await tester.pump();
+ expect(paragraph.selections[0], const TextSelection(baseOffset: 0, extentOffset: 5));
+ expect(find.byKey(toolbarKey), findsOneWidget);
+
+ // Right click anywhere outside previous selection should collapse the
+ // selection.
+ await gesture.down(textOffsetToPosition(paragraph, 7));
+ await tester.pump();
+ await gesture.up();
+ await tester.pump();
+ expect(paragraph.selections.isEmpty, true);
+ expect(find.byKey(toolbarKey), findsOneWidget);
+
+ // Clear selection.
+ await tester.tapAt(textOffsetToPosition(paragraph, 1));
+ await tester.pump();
+ expect(paragraph.selections.isEmpty, true);
+ expect(find.byKey(toolbarKey), findsNothing);
+ },
+ variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.android, TargetPlatform.fuchsia, TargetPlatform.windows }),
+ skip: kIsWeb, // [intended] Web uses its native context menu.
+ );
+
+ testWidgets(
+ 'right-click mouse toggles the context menu on Linux',
+ (WidgetTester tester) async {
+ Set<ContextMenuButtonType> buttonTypes = <ContextMenuButtonType>{};
+ final UniqueKey toolbarKey = UniqueKey();
+ await tester.pumpWidget(
+ MaterialApp(
+ home: SelectableRegion(
+ focusNode: FocusNode(),
+ selectionControls: materialTextSelectionHandleControls,
+ contextMenuBuilder: (
+ BuildContext context,
+ SelectableRegionState selectableRegionState,
+ ) {
+ buttonTypes = selectableRegionState.contextMenuButtonItems
+ .map((ContextMenuButtonItem buttonItem) => buttonItem.type)
+ .toSet();
+ return SizedBox.shrink(key: toolbarKey);
+ },
+ child: const Center(
+ child: Text('How are you'),
+ ),
+ ),
+ ),
+ );
+
+ expect(buttonTypes.isEmpty, true);
+ expect(find.byKey(toolbarKey), findsNothing);
+
+ final RenderParagraph paragraph = tester.renderObject<RenderParagraph>(find.descendant(of: find.text('How are you'), matching: find.byType(RichText)));
+ final TestGesture gesture = await tester.startGesture(textOffsetToPosition(paragraph, 2), kind: PointerDeviceKind.mouse, buttons: kSecondaryMouseButton);
+ addTearDown(gesture.removePointer);
+ await tester.pump();
+ // Selection is collapsed so none is reported.
+ expect(paragraph.selections.isEmpty, true);
+
+ await gesture.up();
+ await tester.pump();
+
+ // Context menu toggled on.
+ expect(buttonTypes.length, 1);
+ expect(buttonTypes, contains(ContextMenuButtonType.selectAll));
+ expect(find.byKey(toolbarKey), findsOneWidget);
+
+ await gesture.down(textOffsetToPosition(paragraph, 6));
+ await tester.pump();
+ expect(paragraph.selections.isEmpty, true);
+
+ await gesture.up();
+ await tester.pump();
+
+ // Context menu toggled off.
+ expect(find.byKey(toolbarKey), findsNothing);
+
+ await gesture.down(textOffsetToPosition(paragraph, 9));
+ await tester.pump();
+ expect(paragraph.selections.isEmpty, true);
+
+ await gesture.up();
+ await tester.pump();
+
+ // Context menu toggled on.
+ expect(buttonTypes.length, 1);
+ expect(buttonTypes, contains(ContextMenuButtonType.selectAll));
+ expect(find.byKey(toolbarKey), findsOneWidget);
+
+ // Clear selection.
+ await tester.tapAt(textOffsetToPosition(paragraph, 1));
+ await tester.pump();
+ expect(paragraph.selections.isEmpty, true);
+ expect(find.byKey(toolbarKey), findsNothing);
+
+ final TestGesture dragGesture = await tester.startGesture(textOffsetToPosition(paragraph, 0), kind: PointerDeviceKind.mouse);
+ addTearDown(dragGesture.removePointer);
+ await tester.pump();
+ await dragGesture.moveTo(textOffsetToPosition(paragraph, 5));
+ await tester.pump();
+ expect(paragraph.selections[0], const TextSelection(baseOffset: 0, extentOffset: 5));
+ await dragGesture.up();
+ await tester.pump();
+
+ // Right click on previous selection should not collapse the selection.
+ await gesture.down(textOffsetToPosition(paragraph, 2));
+ await tester.pump();
+ await gesture.up();
+ await tester.pump();
+ expect(paragraph.selections[0], const TextSelection(baseOffset: 0, extentOffset: 5));
+ expect(find.byKey(toolbarKey), findsOneWidget);
+
+ // Right click anywhere outside previous selection should first toggle the context
+ // menu off.
+ await gesture.down(textOffsetToPosition(paragraph, 7));
+ await tester.pump();
+ await gesture.up();
+ await tester.pump();
+ expect(paragraph.selections[0], const TextSelection(baseOffset: 0, extentOffset: 5));
+ expect(find.byKey(toolbarKey), findsNothing);
+
+ // Right click again should collapse the selection and toggle the context
+ // menu on.
+ await gesture.down(textOffsetToPosition(paragraph, 7));
+ await tester.pump();
+ await gesture.up();
+ await tester.pump();
+ expect(paragraph.selections.isEmpty, true);
+ expect(find.byKey(toolbarKey), findsOneWidget);
+
+ // Clear selection.
+ await tester.tapAt(textOffsetToPosition(paragraph, 1));
+ await tester.pump();
+ expect(paragraph.selections.isEmpty, true);
+ expect(find.byKey(toolbarKey), findsNothing);
+ },
+ variant: TargetPlatformVariant.only(TargetPlatform.linux),
+ skip: kIsWeb, // [intended] Web uses its native context menu.
+ );
+
testWidgets('can copy a selection made with the mouse', (WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
@@ -775,6 +1248,7 @@
final UniqueKey outerText = UniqueKey();
await tester.pumpWidget(
MaterialApp(
+ theme: ThemeData(useMaterial3: false),
home: SelectableRegion(
focusNode: FocusNode(),
selectionControls: materialTextSelectionControls,
@@ -808,6 +1282,7 @@
// Should select "Hello".
expect(paragraph.selections[0], const TextSelection(baseOffset: 124, extentOffset: 129));
},
+ variant: TargetPlatformVariant.only(TargetPlatform.macOS),
skip: isBrowser, // https://github.com/flutter/flutter/issues/61020
);
@@ -1994,6 +2469,51 @@
skip: !kIsWeb, // [intended]
);
});
+
+ testWidgets('Multiple selectables on a single line should be in screen order', (WidgetTester tester) async {
+ // Regression test for https://github.com/flutter/flutter/issues/127942.
+ final UniqueKey outerText = UniqueKey();
+ const TextStyle textStyle = TextStyle(fontSize: 10);
+ await tester.pumpWidget(
+ MaterialApp(
+ home: SelectableRegion(
+ focusNode: FocusNode(),
+ selectionControls: materialTextSelectionControls,
+ child: Scaffold(
+ body: Center(
+ child: Text.rich(
+ const TextSpan(
+ children: <InlineSpan>[
+ TextSpan(text: 'Hello my name is ', style: textStyle),
+ WidgetSpan(
+ child: Text('Dash', style: textStyle),
+ alignment: PlaceholderAlignment.middle,
+ ),
+ TextSpan(text: '.', style: textStyle),
+ ],
+ ),
+ key: outerText,
+ ),
+ ),
+ ),
+ ),
+ ),
+ );
+ final RenderParagraph paragraph1 = tester.renderObject<RenderParagraph>(find.descendant(of: find.byKey(outerText), matching: find.byType(RichText)).first);
+ final TestGesture gesture = await tester.startGesture(textOffsetToPosition(paragraph1, 0), kind: PointerDeviceKind.mouse);
+ addTearDown(gesture.removePointer);
+ await tester.pump();
+ await gesture.up();
+
+ // Select all.
+ await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.keyA, control: true));
+
+ // keyboard copy.
+ await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.keyC, control: true));
+
+ final Map<String, dynamic> clipboardData = mockClipboard.clipboardData as Map<String, dynamic>;
+ expect(clipboardData['text'], 'Hello my name is Dash.');
+ });
}
class SelectionSpy extends LeafRenderObjectWidget {
@@ -2051,8 +2571,7 @@
}
@override
- SelectionGeometry get value => _value;
- SelectionGeometry _value = const SelectionGeometry(
+ final SelectionGeometry value = const SelectionGeometry(
hasContent: true,
status: SelectionStatus.uncollapsed,
startSelectionPoint: SelectionPoint(
@@ -2066,15 +2585,6 @@
handleType: TextSelectionHandleType.left,
),
);
- set value(SelectionGeometry other) {
- if (other == _value) {
- return;
- }
- _value = other;
- for (final VoidCallback callback in listeners) {
- callback();
- }
- }
@override
void pushHandleLayers(LayerLink? startHandle, LayerLink? endHandle) { }
diff --git a/packages/flutter/test/widgets/selectable_text_test.dart b/packages/flutter/test/widgets/selectable_text_test.dart
index 137c855..34099ff 100644
--- a/packages/flutter/test/widgets/selectable_text_test.dart
+++ b/packages/flutter/test/widgets/selectable_text_test.dart
@@ -59,20 +59,23 @@
}
Widget overlayWithEntry(OverlayEntry entry) {
- return Localizations(
- locale: const Locale('en', 'US'),
- delegates: <LocalizationsDelegate<dynamic>>[
- WidgetsLocalizationsDelegate(),
- MaterialLocalizationsDelegate(),
- ],
- child: Directionality(
- textDirection: TextDirection.ltr,
- child: MediaQuery(
- data: const MediaQueryData(size: Size(800.0, 600.0)),
- child: Overlay(
- initialEntries: <OverlayEntry>[
- entry,
- ],
+ return Theme(
+ data: ThemeData(useMaterial3: false),
+ child: Localizations(
+ locale: const Locale('en', 'US'),
+ delegates: <LocalizationsDelegate<dynamic>>[
+ WidgetsLocalizationsDelegate(),
+ MaterialLocalizationsDelegate(),
+ ],
+ child: Directionality(
+ textDirection: TextDirection.ltr,
+ child: MediaQuery(
+ data: const MediaQueryData(size: Size(800.0, 600.0)),
+ child: Overlay(
+ initialEntries: <OverlayEntry>[
+ entry,
+ ],
+ ),
),
),
),
@@ -80,19 +83,22 @@
}
Widget boilerplate({ Widget? child }) {
- return Localizations(
- locale: const Locale('en', 'US'),
- delegates: <LocalizationsDelegate<dynamic>>[
- WidgetsLocalizationsDelegate(),
- MaterialLocalizationsDelegate(),
- ],
- child: Directionality(
- textDirection: TextDirection.ltr,
- child: MediaQuery(
- data: const MediaQueryData(size: Size(800.0, 600.0)),
- child: Center(
- child: Material(
- child: child,
+ return Theme(
+ data: ThemeData(useMaterial3: false),
+ child:Localizations(
+ locale: const Locale('en', 'US'),
+ delegates: <LocalizationsDelegate<dynamic>>[
+ WidgetsLocalizationsDelegate(),
+ MaterialLocalizationsDelegate(),
+ ],
+ child: Directionality(
+ textDirection: TextDirection.ltr,
+ child: MediaQuery(
+ data: const MediaQueryData(size: Size(800.0, 600.0)),
+ child: Center(
+ child: Material(
+ child: child,
+ ),
),
),
),
@@ -100,6 +106,7 @@
);
}
+
Future<void> skipPastScrollingAnimation(WidgetTester tester) async {
await tester.pump();
await tester.pump(const Duration(milliseconds: 200));
@@ -4130,7 +4137,7 @@
(WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
- theme: ThemeData(platform: TargetPlatform.android),
+ theme: ThemeData(platform: TargetPlatform.android, useMaterial3: false),
home: const Material(
child: Center(
child: SelectableText('something'),
@@ -4153,7 +4160,7 @@
(WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
- theme: ThemeData(platform: TargetPlatform.android),
+ theme: ThemeData(platform: TargetPlatform.android, useMaterial3: false),
home: const Material(
child: Center(
child: SelectableText(
@@ -4174,7 +4181,7 @@
await tester.pumpWidget(
MaterialApp(
- theme: ThemeData(platform: TargetPlatform.android),
+ theme: ThemeData(platform: TargetPlatform.android, useMaterial3: false),
home: const Material(
child: Center(
child: SelectableText(
@@ -4200,7 +4207,7 @@
(WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
- theme: ThemeData(platform: TargetPlatform.android),
+ theme: ThemeData(platform: TargetPlatform.android, useMaterial3: false),
home: const Material(
child: Center(
child: SelectableText(
@@ -4224,7 +4231,7 @@
(WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
- theme: ThemeData(platform: TargetPlatform.android),
+ theme: ThemeData(platform: TargetPlatform.android, useMaterial3: false),
home: const Material(
child: Center(
child: SelectableText(
@@ -4256,7 +4263,7 @@
(WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
- theme: ThemeData(platform: TargetPlatform.android),
+ theme: ThemeData(platform: TargetPlatform.android, useMaterial3: false),
home: const Material(
child: Center(
child: SelectableText(
@@ -4285,7 +4292,7 @@
(WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
- theme: ThemeData(platform: TargetPlatform.android),
+ theme: ThemeData(platform: TargetPlatform.android, useMaterial3: false),
home: const Material(
child: Center(
child: SelectableText(
@@ -4314,7 +4321,7 @@
(WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
- theme: ThemeData(platform: TargetPlatform.android),
+ theme: ThemeData(platform: TargetPlatform.android, useMaterial3: false),
home: const Material(
child: Center(
child: SelectableText(
@@ -5019,6 +5026,7 @@
await tester.pumpWidget(
MaterialApp(
+ theme: ThemeData(useMaterial3: false),
home: Material(
child: Center(
child: SelectableText(
@@ -5080,8 +5088,9 @@
testWidgets('text selection style 1', (WidgetTester tester) async {
await tester.pumpWidget(
- const MaterialApp(
- home: Material(
+ MaterialApp(
+ theme: ThemeData(useMaterial3: false),
+ home: const Material(
child: Center(
child: Column(
children: <Widget>[
@@ -5132,8 +5141,9 @@
testWidgets('text selection style 2', (WidgetTester tester) async {
await tester.pumpWidget(
- const MaterialApp(
- home: Material(
+ MaterialApp(
+ theme: ThemeData(useMaterial3: false),
+ home: const Material(
child: Center(
child: Column(
children: <Widget>[
@@ -5184,6 +5194,7 @@
testWidgets('keeps alive when has focus', (WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
+ theme: ThemeData(useMaterial3: false),
home: DefaultTabController(
length: 2,
child: Scaffold(
@@ -5347,8 +5358,9 @@
const TextStyle textStyle = TextStyle(color: Color(0xff00ff00), fontSize: 12.0);
await tester.pumpWidget(
- const MaterialApp(
- home: SelectableText.rich(
+ MaterialApp(
+ theme: ThemeData(useMaterial3: false),
+ home: const SelectableText.rich(
TextSpan(
text: 'Abcd',
style: textStyle,
@@ -5367,6 +5379,7 @@
await tester.pumpWidget(
MaterialApp(
+ theme: ThemeData(useMaterial3: false),
home: SelectableText(
'I love Flutter!',
onSelectionChanged: (TextSelection s, _) {
@@ -5406,6 +5419,7 @@
TextSelection? selection;
await tester.pumpWidget(
MaterialApp(
+ theme: ThemeData(useMaterial3: false),
home: Material(
child: Builder(
builder: (BuildContext context) {
diff --git a/packages/flutter/test/widgets/semantics_10_test.dart b/packages/flutter/test/widgets/semantics_10_test.dart
index 4b452b1..0ef416e 100644
--- a/packages/flutter/test/widgets/semantics_10_test.dart
+++ b/packages/flutter/test/widgets/semantics_10_test.dart
@@ -96,13 +96,13 @@
void describeSemanticsConfiguration(SemanticsConfiguration config) {
super.describeSemanticsConfiguration(config);
- if (!_isSemanticBoundary) {
+ if (!isSemanticBoundary) {
return;
}
config
- ..isSemanticBoundary = _isSemanticBoundary
- ..label = _label
+ ..isSemanticBoundary = isSemanticBoundary
+ ..label = label
..textDirection = TextDirection.ltr;
}
diff --git a/packages/flutter/test/widgets/semantics_child_configs_delegate_test.dart b/packages/flutter/test/widgets/semantics_child_configs_delegate_test.dart
index 33f3b28..a562a53 100644
--- a/packages/flutter/test/widgets/semantics_child_configs_delegate_test.dart
+++ b/packages/flutter/test/widgets/semantics_child_configs_delegate_test.dart
@@ -357,6 +357,6 @@
@override
void describeSemanticsConfiguration(SemanticsConfiguration config) {
- config.childConfigurationsDelegate = _delegate;
+ config.childConfigurationsDelegate = delegate;
}
}
diff --git a/packages/flutter/test/widgets/shortcuts_test.dart b/packages/flutter/test/widgets/shortcuts_test.dart
index 74d1d59..0481f8c 100644
--- a/packages/flutter/test/widgets/shortcuts_test.dart
+++ b/packages/flutter/test/widgets/shortcuts_test.dart
@@ -601,18 +601,12 @@
testWidgets('Shortcuts.manager lets manager handle shortcuts', (WidgetTester tester) async {
final GlobalKey containerKey = GlobalKey();
final List<LogicalKeyboardKey> pressedKeys = <LogicalKeyboardKey>[];
- bool shortcutsSet = false;
- void onShortcutsSet() {
- shortcutsSet = true;
- }
final TestShortcutManager testManager = TestShortcutManager(
pressedKeys,
- onShortcutsSet: onShortcutsSet,
shortcuts: <LogicalKeySet, Intent>{
LogicalKeySet(LogicalKeyboardKey.shift): const TestIntent(),
},
);
- shortcutsSet = false;
bool invoked = false;
await tester.pumpWidget(
Actions(
@@ -636,7 +630,6 @@
await tester.pump();
await tester.sendKeyDownEvent(LogicalKeyboardKey.shiftLeft);
expect(invoked, isTrue);
- expect(shortcutsSet, isFalse);
expect(pressedKeys, equals(<LogicalKeyboardKey>[LogicalKeyboardKey.shiftLeft]));
});
@@ -1953,10 +1946,9 @@
}
class TestShortcutManager extends ShortcutManager {
- TestShortcutManager(this.keys, { super.shortcuts, this.onShortcutsSet });
+ TestShortcutManager(this.keys, { super.shortcuts });
List<LogicalKeyboardKey> keys;
- VoidCallback? onShortcutsSet;
@override
KeyEventResult handleKeypress(BuildContext context, RawKeyEvent event) {
diff --git a/packages/flutter/test/widgets/sliver_fill_remaining_test.dart b/packages/flutter/test/widgets/sliver_fill_remaining_test.dart
index 79f0b50..f0279e2 100644
--- a/packages/flutter/test/widgets/sliver_fill_remaining_test.dart
+++ b/packages/flutter/test/widgets/sliver_fill_remaining_test.dart
@@ -24,6 +24,7 @@
}) {
return MaterialApp(
theme: ThemeData(
+ useMaterial3: false,
materialTapTargetSize: MaterialTapTargetSize.padded,
),
home: Scaffold(
diff --git a/packages/flutter/test/widgets/slivers_appbar_floating_pinned_test.dart b/packages/flutter/test/widgets/slivers_appbar_floating_pinned_test.dart
index 4831cb6..ff3ec8c 100644
--- a/packages/flutter/test/widgets/slivers_appbar_floating_pinned_test.dart
+++ b/packages/flutter/test/widgets/slivers_appbar_floating_pinned_test.dart
@@ -244,35 +244,25 @@
testWidgets('Sliver appbars - floating and pinned - second app bar stacks below', (WidgetTester tester) async {
final ScrollController controller = ScrollController();
await tester.pumpWidget(
- Localizations(
- locale: const Locale('en', 'us'),
- delegates: const <LocalizationsDelegate<dynamic>>[
- DefaultWidgetsLocalizations.delegate,
- DefaultMaterialLocalizations.delegate,
- ],
- child: Directionality(
- textDirection: TextDirection.ltr,
- child: MediaQuery(
- data: const MediaQueryData(),
- child: CustomScrollView(
- controller: controller,
- slivers: <Widget>[
- const SliverAppBar(floating: true, pinned: true, expandedHeight: 200.0, title: Text('A')),
- const SliverAppBar(primary: false, pinned: true, title: Text('B')),
- SliverList(
- delegate: SliverChildListDelegate(
- const <Widget>[
- Text('C'),
- Text('D'),
- SizedBox(height: 500.0),
- Text('E'),
- SizedBox(height: 500.0),
- ],
- ),
- ),
- ],
+ MaterialApp(
+ theme: ThemeData(useMaterial3: false),
+ home: CustomScrollView(
+ controller: controller,
+ slivers: <Widget>[
+ const SliverAppBar(floating: true, pinned: true, expandedHeight: 200.0, title: Text('A')),
+ const SliverAppBar(primary: false, pinned: true, title: Text('B')),
+ SliverList(
+ delegate: SliverChildListDelegate(
+ const <Widget>[
+ Text('C'),
+ Text('D'),
+ SizedBox(height: 500.0),
+ Text('E'),
+ SizedBox(height: 500.0),
+ ],
+ ),
),
- ),
+ ],
),
),
);
diff --git a/packages/flutter/test/widgets/slivers_keepalive_test.dart b/packages/flutter/test/widgets/slivers_keepalive_test.dart
index 5065232..ae7dc37 100644
--- a/packages/flutter/test/widgets/slivers_keepalive_test.dart
+++ b/packages/flutter/test/widgets/slivers_keepalive_test.dart
@@ -319,7 +319,7 @@
WidgetTest2(text: 'child 2', key: UniqueKey()),
];
await tester.pumpWidget(
- SwitchingSliverListTest(viewportFraction: 0.1, children: childList),
+ SwitchingSliverListTest(children: childList),
);
final _WidgetTest0State state0 = tester.state(find.byType(WidgetTest0));
final _WidgetTest1State state1 = tester.state(find.byType(WidgetTest1));
@@ -330,32 +330,32 @@
childList = createSwitchedChildList(childList, 0, 2);
await tester.pumpWidget(
- SwitchingSliverListTest(viewportFraction: 0.1, children: childList),
+ SwitchingSliverListTest(children: childList),
);
childList = createSwitchedChildList(childList, 1, 2);
await tester.pumpWidget(
- SwitchingSliverListTest(viewportFraction: 0.1, children: childList),
+ SwitchingSliverListTest(children: childList),
);
childList = createSwitchedChildList(childList, 1, 2);
await tester.pumpWidget(
- SwitchingSliverListTest(viewportFraction: 0.1, children: childList),
+ SwitchingSliverListTest(children: childList),
);
childList = createSwitchedChildList(childList, 0, 1);
await tester.pumpWidget(
- SwitchingSliverListTest(viewportFraction: 0.1, children: childList),
+ SwitchingSliverListTest(children: childList),
);
childList = createSwitchedChildList(childList, 0, 2);
await tester.pumpWidget(
- SwitchingSliverListTest(viewportFraction: 0.1, children: childList),
+ SwitchingSliverListTest(children: childList),
);
childList = createSwitchedChildList(childList, 0, 1);
await tester.pumpWidget(
- SwitchingSliverListTest(viewportFraction: 0.1, children: childList),
+ SwitchingSliverListTest(children: childList),
);
expect(state0.hasBeenDisposed, false);
expect(state1.hasBeenDisposed, true);
@@ -369,7 +369,7 @@
WidgetTest2(text: 'child 2', key: UniqueKey()),
];
await tester.pumpWidget(
- SwitchingSliverListTest(viewportFraction: 0.1, children: childList),
+ SwitchingSliverListTest(children: childList),
);
final _WidgetTest0State state0 = tester.state(find.byType(WidgetTest0));
final _WidgetTest1State state1 = tester.state(find.byType(WidgetTest1));
@@ -381,7 +381,7 @@
childList = createSwitchedChildList(childList, 0, 1);
childList.removeAt(2);
await tester.pumpWidget(
- SwitchingSliverListTest(viewportFraction: 0.1, children: childList),
+ SwitchingSliverListTest(children: childList),
);
expect(find.text('child 0'), findsOneWidget);
expect(find.text('child 1'), findsOneWidget);
@@ -505,12 +505,10 @@
class SwitchingSliverListTest extends StatelessWidget {
const SwitchingSliverListTest({
required this.children,
- this.viewportFraction = 1.0,
super.key,
});
final List<Widget> children;
- final double viewportFraction;
@override
Widget build(BuildContext context) {
diff --git a/packages/flutter/test/widgets/slivers_test.dart b/packages/flutter/test/widgets/slivers_test.dart
index 6dbee9a..8f7bab5 100644
--- a/packages/flutter/test/widgets/slivers_test.dart
+++ b/packages/flutter/test/widgets/slivers_test.dart
@@ -426,6 +426,7 @@
}
await tester.pumpWidget(
MaterialApp(
+ theme: ThemeData(useMaterial3: false),
home: Scaffold(
body: CustomScrollView(
slivers: <Widget> [
diff --git a/packages/flutter/test/widgets/snapshot_widget_test.dart b/packages/flutter/test/widgets/snapshot_widget_test.dart
index 751a610..05512ba 100644
--- a/packages/flutter/test/widgets/snapshot_widget_test.dart
+++ b/packages/flutter/test/widgets/snapshot_widget_test.dart
@@ -335,10 +335,6 @@
super.removeListener(listener);
}
- void notify() {
- notifyListeners();
- }
-
@override
void paintSnapshot(PaintingContext context, Offset offset, Size size, ui.Image image, Size sourceSize, double pixelRatio) {
count += 1;
diff --git a/packages/flutter/test/widgets/tap_and_drag_gestures_test.dart b/packages/flutter/test/widgets/tap_and_drag_gestures_test.dart
index 972e7c0..33027be 100644
--- a/packages/flutter/test/widgets/tap_and_drag_gestures_test.dart
+++ b/packages/flutter/test/widgets/tap_and_drag_gestures_test.dart
@@ -694,6 +694,44 @@
'panend#2']);
});
+ // This is a regression test for https://github.com/flutter/flutter/issues/129161.
+ testGesture('Beats TapGestureRecognizer and DoubleTapGestureRecognizer when the pointer has not moved and this recognizer is the first in the arena', (GestureTester tester) {
+ setUpTapAndPanGestureRecognizer();
+
+ final TapGestureRecognizer taps = TapGestureRecognizer()
+ ..onTapDown = (TapDownDetails details) {
+ events.add('tapdown');
+ }
+ ..onTapUp = (TapUpDetails details) {
+ events.add('tapup');
+ }
+ ..onTapCancel = () {
+ events.add('tapscancel');
+ };
+
+ final DoubleTapGestureRecognizer doubleTaps = DoubleTapGestureRecognizer()
+ ..onDoubleTapDown = (TapDownDetails details) {
+ events.add('doubletapdown');
+ }
+ ..onDoubleTap = () {
+ events.add('doubletapup');
+ }
+ ..onDoubleTapCancel = () {
+ events.add('doubletapcancel');
+ };
+
+ tapAndDrag.addPointer(down1);
+ taps.addPointer(down1);
+ doubleTaps.addPointer(down1);
+ tester.closeArena(1);
+ tester.route(down1);
+ tester.route(up1);
+ GestureBinding.instance.gestureArena.sweep(1);
+ // Wait for GestureArena to resolve itself.
+ tester.async.elapse(kDoubleTapTimeout);
+ expect(events, <String>['down#1', 'up#1']);
+ });
+
testGesture('Beats TapGestureRecognizer when the pointer has not moved and this recognizer is the first in the arena', (GestureTester tester) {
setUpTapAndPanGestureRecognizer();
diff --git a/packages/flutter/test/widgets/text_golden_test.dart b/packages/flutter/test/widgets/text_golden_test.dart
index fe8661d..4267da2 100644
--- a/packages/flutter/test/widgets/text_golden_test.dart
+++ b/packages/flutter/test/widgets/text_golden_test.dart
@@ -191,6 +191,7 @@
testWidgets('Text Fade', (WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
+ theme: ThemeData(useMaterial3: false),
home: Scaffold(
backgroundColor: Colors.transparent,
body: RepaintBoundary(
@@ -520,7 +521,7 @@
testWidgets('Text Inline widget', (WidgetTester tester) async {
await tester.pumpWidget(
- Center(
+ Theme(data: ThemeData(useMaterial3: false), child: Center(
child: RepaintBoundary(
child: Material(
child: Directionality(
@@ -604,7 +605,7 @@
),
),
),
- ),
+ )),
);
await expectLater(
find.byType(Container),
@@ -616,6 +617,7 @@
await tester.pumpWidget(
Center(
child: MaterialApp(
+ theme: ThemeData(useMaterial3: false),
home: RepaintBoundary(
child: Material(
child: Container(
@@ -662,6 +664,7 @@
await tester.pumpWidget(
Center(
child: MaterialApp(
+ theme: ThemeData(useMaterial3: false),
home: RepaintBoundary(
child: Material(
child: Container(
@@ -788,97 +791,100 @@
testWidgets('Text Inline widget baseline', (WidgetTester tester) async {
await tester.pumpWidget(
- Center(
- child: RepaintBoundary(
- child: Material(
- child: Directionality(
- textDirection: TextDirection.ltr,
- child: Container(
- width: 400.0,
- height: 200.0,
- decoration: const BoxDecoration(
- color: Color(0xff00ff00),
- ),
- child: ConstrainedBox(
- constraints: const BoxConstraints(maxWidth: 200, maxHeight: 100),
- child: const Text.rich(
- TextSpan(
- text: 'C ',
- style: TextStyle(
- fontSize: 16,
- ),
- children: <InlineSpan>[
- WidgetSpan(
- alignment: PlaceholderAlignment.baseline,
- baseline: TextBaseline.alphabetic,
- child: Checkbox(value: true, onChanged: null),
+ Theme(
+ data: ThemeData(useMaterial3: false),
+ child: Center(
+ child: RepaintBoundary(
+ child: Material(
+ child: Directionality(
+ textDirection: TextDirection.ltr,
+ child: Container(
+ width: 400.0,
+ height: 200.0,
+ decoration: const BoxDecoration(
+ color: Color(0xff00ff00),
+ ),
+ child: ConstrainedBox(
+ constraints: const BoxConstraints(maxWidth: 200, maxHeight: 100),
+ child: const Text.rich(
+ TextSpan(
+ text: 'C ',
+ style: TextStyle(
+ fontSize: 16,
),
- WidgetSpan(
- child: Checkbox(value: false, onChanged: null),
- ),
- TextSpan(text: 'He ', style: TextStyle(fontSize: 20)),
- WidgetSpan(
- alignment: PlaceholderAlignment.baseline,
- baseline: TextBaseline.alphabetic,
- child: SizedBox(
- width: 50.0,
- height: 55.0,
- child: DecoratedBox(
- decoration: BoxDecoration(
- color: Color(0xffffff00),
- ),
- child: Center(
- child:SizedBox(
- width: 10.0,
- height: 15.0,
- child: DecoratedBox(
- decoration: BoxDecoration(
- color: Color(0xffff0000),
+ children: <InlineSpan>[
+ WidgetSpan(
+ alignment: PlaceholderAlignment.baseline,
+ baseline: TextBaseline.alphabetic,
+ child: Checkbox(value: true, onChanged: null),
+ ),
+ WidgetSpan(
+ child: Checkbox(value: false, onChanged: null),
+ ),
+ TextSpan(text: 'He ', style: TextStyle(fontSize: 20)),
+ WidgetSpan(
+ alignment: PlaceholderAlignment.baseline,
+ baseline: TextBaseline.alphabetic,
+ child: SizedBox(
+ width: 50.0,
+ height: 55.0,
+ child: DecoratedBox(
+ decoration: BoxDecoration(
+ color: Color(0xffffff00),
+ ),
+ child: Center(
+ child:SizedBox(
+ width: 10.0,
+ height: 15.0,
+ child: DecoratedBox(
+ decoration: BoxDecoration(
+ color: Color(0xffff0000),
+ ),
),
),
),
),
),
),
- ),
- TextSpan(text: 'hello world! seize the day!'),
- WidgetSpan(
- alignment: PlaceholderAlignment.baseline,
- baseline: TextBaseline.alphabetic,
- child: Checkbox(value: false, onChanged: null),
- ),
- WidgetSpan(
- alignment: PlaceholderAlignment.baseline,
- baseline: TextBaseline.alphabetic,
- child: SizedBox(
- width: 20,
- height: 20,
- child: Checkbox(value: true, onChanged: null),
+ TextSpan(text: 'hello world! seize the day!'),
+ WidgetSpan(
+ alignment: PlaceholderAlignment.baseline,
+ baseline: TextBaseline.alphabetic,
+ child: Checkbox(value: false, onChanged: null),
),
- ),
- WidgetSpan(
- alignment: PlaceholderAlignment.baseline,
- baseline: TextBaseline.alphabetic,
- child: Checkbox(value: false, onChanged: null),
- ),
- WidgetSpan(
- alignment: PlaceholderAlignment.baseline,
- baseline: TextBaseline.alphabetic,
- child: SizedBox(
- width: 20,
- height: 20,
- child: Checkbox(value: true, onChanged: null),
+ WidgetSpan(
+ alignment: PlaceholderAlignment.baseline,
+ baseline: TextBaseline.alphabetic,
+ child: SizedBox(
+ width: 20,
+ height: 20,
+ child: Checkbox(value: true, onChanged: null),
+ ),
),
- ),
- WidgetSpan(
- alignment: PlaceholderAlignment.baseline,
- baseline: TextBaseline.alphabetic,
- child: Text('embedded'),
- ),
- TextSpan(text: 'ref'),
- ],
+ WidgetSpan(
+ alignment: PlaceholderAlignment.baseline,
+ baseline: TextBaseline.alphabetic,
+ child: Checkbox(value: false, onChanged: null),
+ ),
+ WidgetSpan(
+ alignment: PlaceholderAlignment.baseline,
+ baseline: TextBaseline.alphabetic,
+ child: SizedBox(
+ width: 20,
+ height: 20,
+ child: Checkbox(value: true, onChanged: null),
+ ),
+ ),
+ WidgetSpan(
+ alignment: PlaceholderAlignment.baseline,
+ baseline: TextBaseline.alphabetic,
+ child: Text('embedded'),
+ ),
+ TextSpan(text: 'ref'),
+ ],
+ ),
+ textDirection: TextDirection.ltr,
),
- textDirection: TextDirection.ltr,
),
),
),
@@ -895,97 +901,100 @@
testWidgets('Text Inline widget aboveBaseline', (WidgetTester tester) async {
await tester.pumpWidget(
- Center(
- child: RepaintBoundary(
- child: Material(
- child: Directionality(
- textDirection: TextDirection.ltr,
- child: Container(
- width: 400.0,
- height: 200.0,
- decoration: const BoxDecoration(
- color: Color(0xff00ff00),
- ),
- child: ConstrainedBox(
- constraints: const BoxConstraints(maxWidth: 200, maxHeight: 100),
- child: const Text.rich(
- TextSpan(
- text: 'C ',
- style: TextStyle(
- fontSize: 16,
- ),
- children: <InlineSpan>[
- WidgetSpan(
- alignment: PlaceholderAlignment.aboveBaseline,
- baseline: TextBaseline.alphabetic,
- child: Checkbox(value: true, onChanged: null),
+ Theme(
+ data: ThemeData(useMaterial3: false),
+ child: Center(
+ child: RepaintBoundary(
+ child: Material(
+ child: Directionality(
+ textDirection: TextDirection.ltr,
+ child: Container(
+ width: 400.0,
+ height: 200.0,
+ decoration: const BoxDecoration(
+ color: Color(0xff00ff00),
+ ),
+ child: ConstrainedBox(
+ constraints: const BoxConstraints(maxWidth: 200, maxHeight: 100),
+ child: const Text.rich(
+ TextSpan(
+ text: 'C ',
+ style: TextStyle(
+ fontSize: 16,
),
- WidgetSpan(
- child: Checkbox(value: false, onChanged: null),
- ),
- TextSpan(text: 'He ', style: TextStyle(fontSize: 20)),
- WidgetSpan(
- alignment: PlaceholderAlignment.aboveBaseline,
- baseline: TextBaseline.alphabetic,
- child: SizedBox(
- width: 50.0,
- height: 55.0,
- child: DecoratedBox(
- decoration: BoxDecoration(
- color: Color(0xffffff00),
- ),
- child: Center(
- child:SizedBox(
- width: 10.0,
- height: 15.0,
- child: DecoratedBox(
- decoration: BoxDecoration(
- color: Color(0xffff0000),
+ children: <InlineSpan>[
+ WidgetSpan(
+ alignment: PlaceholderAlignment.aboveBaseline,
+ baseline: TextBaseline.alphabetic,
+ child: Checkbox(value: true, onChanged: null),
+ ),
+ WidgetSpan(
+ child: Checkbox(value: false, onChanged: null),
+ ),
+ TextSpan(text: 'He ', style: TextStyle(fontSize: 20)),
+ WidgetSpan(
+ alignment: PlaceholderAlignment.aboveBaseline,
+ baseline: TextBaseline.alphabetic,
+ child: SizedBox(
+ width: 50.0,
+ height: 55.0,
+ child: DecoratedBox(
+ decoration: BoxDecoration(
+ color: Color(0xffffff00),
+ ),
+ child: Center(
+ child:SizedBox(
+ width: 10.0,
+ height: 15.0,
+ child: DecoratedBox(
+ decoration: BoxDecoration(
+ color: Color(0xffff0000),
+ ),
),
),
),
),
),
),
- ),
- TextSpan(text: 'hello world! seize the day!'),
- WidgetSpan(
- alignment: PlaceholderAlignment.aboveBaseline,
- baseline: TextBaseline.alphabetic,
- child: Checkbox(value: false, onChanged: null),
- ),
- WidgetSpan(
- alignment: PlaceholderAlignment.aboveBaseline,
- baseline: TextBaseline.alphabetic,
- child: SizedBox(
- width: 20,
- height: 20,
- child: Checkbox(value: true, onChanged: null),
+ TextSpan(text: 'hello world! seize the day!'),
+ WidgetSpan(
+ alignment: PlaceholderAlignment.aboveBaseline,
+ baseline: TextBaseline.alphabetic,
+ child: Checkbox(value: false, onChanged: null),
),
- ),
- WidgetSpan(
- alignment: PlaceholderAlignment.aboveBaseline,
- baseline: TextBaseline.alphabetic,
- child: Checkbox(value: false, onChanged: null),
- ),
- WidgetSpan(
- alignment: PlaceholderAlignment.aboveBaseline,
- baseline: TextBaseline.alphabetic,
- child: SizedBox(
- width: 20,
- height: 20,
- child: Checkbox(value: true, onChanged: null),
+ WidgetSpan(
+ alignment: PlaceholderAlignment.aboveBaseline,
+ baseline: TextBaseline.alphabetic,
+ child: SizedBox(
+ width: 20,
+ height: 20,
+ child: Checkbox(value: true, onChanged: null),
+ ),
),
- ),
- WidgetSpan(
- alignment: PlaceholderAlignment.aboveBaseline,
- baseline: TextBaseline.alphabetic,
- child: Text('embedded'),
- ),
- TextSpan(text: 'ref'),
- ],
+ WidgetSpan(
+ alignment: PlaceholderAlignment.aboveBaseline,
+ baseline: TextBaseline.alphabetic,
+ child: Checkbox(value: false, onChanged: null),
+ ),
+ WidgetSpan(
+ alignment: PlaceholderAlignment.aboveBaseline,
+ baseline: TextBaseline.alphabetic,
+ child: SizedBox(
+ width: 20,
+ height: 20,
+ child: Checkbox(value: true, onChanged: null),
+ ),
+ ),
+ WidgetSpan(
+ alignment: PlaceholderAlignment.aboveBaseline,
+ baseline: TextBaseline.alphabetic,
+ child: Text('embedded'),
+ ),
+ TextSpan(text: 'ref'),
+ ],
+ ),
+ textDirection: TextDirection.ltr,
),
- textDirection: TextDirection.ltr,
),
),
),
@@ -1002,97 +1011,100 @@
testWidgets('Text Inline widget belowBaseline', (WidgetTester tester) async {
await tester.pumpWidget(
- Center(
- child: RepaintBoundary(
- child: Material(
- child: Directionality(
- textDirection: TextDirection.ltr,
- child: Container(
- width: 400.0,
- height: 200.0,
- decoration: const BoxDecoration(
- color: Color(0xff00ff00),
- ),
- child: ConstrainedBox(
- constraints: const BoxConstraints(maxWidth: 200, maxHeight: 100),
- child: const Text.rich(
- TextSpan(
- text: 'C ',
- style: TextStyle(
- fontSize: 16,
- ),
- children: <InlineSpan>[
- WidgetSpan(
- alignment: PlaceholderAlignment.belowBaseline,
- baseline: TextBaseline.alphabetic,
- child: Checkbox(value: true, onChanged: null),
+ Theme(
+ data: ThemeData(useMaterial3: false),
+ child: Center(
+ child: RepaintBoundary(
+ child: Material(
+ child: Directionality(
+ textDirection: TextDirection.ltr,
+ child: Container(
+ width: 400.0,
+ height: 200.0,
+ decoration: const BoxDecoration(
+ color: Color(0xff00ff00),
+ ),
+ child: ConstrainedBox(
+ constraints: const BoxConstraints(maxWidth: 200, maxHeight: 100),
+ child: const Text.rich(
+ TextSpan(
+ text: 'C ',
+ style: TextStyle(
+ fontSize: 16,
),
- WidgetSpan(
- child: Checkbox(value: false, onChanged: null),
- ),
- TextSpan(text: 'He ', style: TextStyle(fontSize: 20)),
- WidgetSpan(
- alignment: PlaceholderAlignment.belowBaseline,
- baseline: TextBaseline.alphabetic,
- child: SizedBox(
- width: 50.0,
- height: 55.0,
- child: DecoratedBox(
- decoration: BoxDecoration(
- color: Color(0xffffff00),
- ),
- child: Center(
- child:SizedBox(
- width: 10.0,
- height: 15.0,
- child: DecoratedBox(
- decoration: BoxDecoration(
- color: Color(0xffff0000),
+ children: <InlineSpan>[
+ WidgetSpan(
+ alignment: PlaceholderAlignment.belowBaseline,
+ baseline: TextBaseline.alphabetic,
+ child: Checkbox(value: true, onChanged: null),
+ ),
+ WidgetSpan(
+ child: Checkbox(value: false, onChanged: null),
+ ),
+ TextSpan(text: 'He ', style: TextStyle(fontSize: 20)),
+ WidgetSpan(
+ alignment: PlaceholderAlignment.belowBaseline,
+ baseline: TextBaseline.alphabetic,
+ child: SizedBox(
+ width: 50.0,
+ height: 55.0,
+ child: DecoratedBox(
+ decoration: BoxDecoration(
+ color: Color(0xffffff00),
+ ),
+ child: Center(
+ child:SizedBox(
+ width: 10.0,
+ height: 15.0,
+ child: DecoratedBox(
+ decoration: BoxDecoration(
+ color: Color(0xffff0000),
+ ),
),
),
),
),
),
),
- ),
- TextSpan(text: 'hello world! seize the day!'),
- WidgetSpan(
- alignment: PlaceholderAlignment.belowBaseline,
- baseline: TextBaseline.alphabetic,
- child: Checkbox(value: false, onChanged: null),
- ),
- WidgetSpan(
- alignment: PlaceholderAlignment.belowBaseline,
- baseline: TextBaseline.alphabetic,
- child: SizedBox(
- width: 20,
- height: 20,
- child: Checkbox(value: true, onChanged: null),
+ TextSpan(text: 'hello world! seize the day!'),
+ WidgetSpan(
+ alignment: PlaceholderAlignment.belowBaseline,
+ baseline: TextBaseline.alphabetic,
+ child: Checkbox(value: false, onChanged: null),
),
- ),
- WidgetSpan(
- alignment: PlaceholderAlignment.belowBaseline,
- baseline: TextBaseline.alphabetic,
- child: Checkbox(value: false, onChanged: null),
- ),
- WidgetSpan(
- alignment: PlaceholderAlignment.belowBaseline,
- baseline: TextBaseline.alphabetic,
- child: SizedBox(
- width: 20,
- height: 20,
- child: Checkbox(value: true, onChanged: null),
+ WidgetSpan(
+ alignment: PlaceholderAlignment.belowBaseline,
+ baseline: TextBaseline.alphabetic,
+ child: SizedBox(
+ width: 20,
+ height: 20,
+ child: Checkbox(value: true, onChanged: null),
+ ),
),
- ),
- WidgetSpan(
- alignment: PlaceholderAlignment.belowBaseline,
- baseline: TextBaseline.alphabetic,
- child: Text('embedded'),
- ),
- TextSpan(text: 'ref'),
- ],
+ WidgetSpan(
+ alignment: PlaceholderAlignment.belowBaseline,
+ baseline: TextBaseline.alphabetic,
+ child: Checkbox(value: false, onChanged: null),
+ ),
+ WidgetSpan(
+ alignment: PlaceholderAlignment.belowBaseline,
+ baseline: TextBaseline.alphabetic,
+ child: SizedBox(
+ width: 20,
+ height: 20,
+ child: Checkbox(value: true, onChanged: null),
+ ),
+ ),
+ WidgetSpan(
+ alignment: PlaceholderAlignment.belowBaseline,
+ baseline: TextBaseline.alphabetic,
+ child: Text('embedded'),
+ ),
+ TextSpan(text: 'ref'),
+ ],
+ ),
+ textDirection: TextDirection.ltr,
),
- textDirection: TextDirection.ltr,
),
),
),
@@ -1109,97 +1121,100 @@
testWidgets('Text Inline widget top', (WidgetTester tester) async {
await tester.pumpWidget(
- Center(
- child: RepaintBoundary(
- child: Material(
- child: Directionality(
- textDirection: TextDirection.ltr,
- child: Container(
- width: 400.0,
- height: 200.0,
- decoration: const BoxDecoration(
- color: Color(0xff00ff00),
- ),
- child: ConstrainedBox(
- constraints: const BoxConstraints(maxWidth: 200, maxHeight: 100),
- child: const Text.rich(
- TextSpan(
- text: 'C ',
- style: TextStyle(
- fontSize: 16,
- ),
- children: <InlineSpan>[
- WidgetSpan(
- alignment: PlaceholderAlignment.top,
- baseline: TextBaseline.alphabetic,
- child: Checkbox(value: true, onChanged: null),
+ Theme(
+ data: ThemeData(useMaterial3: false),
+ child: Center(
+ child: RepaintBoundary(
+ child: Material(
+ child: Directionality(
+ textDirection: TextDirection.ltr,
+ child: Container(
+ width: 400.0,
+ height: 200.0,
+ decoration: const BoxDecoration(
+ color: Color(0xff00ff00),
+ ),
+ child: ConstrainedBox(
+ constraints: const BoxConstraints(maxWidth: 200, maxHeight: 100),
+ child: const Text.rich(
+ TextSpan(
+ text: 'C ',
+ style: TextStyle(
+ fontSize: 16,
),
- WidgetSpan(
- child: Checkbox(value: false, onChanged: null),
- ),
- TextSpan(text: 'He ', style: TextStyle(fontSize: 20)),
- WidgetSpan(
- alignment: PlaceholderAlignment.top,
- baseline: TextBaseline.alphabetic,
- child: SizedBox(
- width: 50.0,
- height: 55.0,
- child: DecoratedBox(
- decoration: BoxDecoration(
- color: Color(0xffffff00),
- ),
- child: Center(
- child:SizedBox(
- width: 10.0,
- height: 15.0,
- child: DecoratedBox(
- decoration: BoxDecoration(
- color: Color(0xffff0000),
+ children: <InlineSpan>[
+ WidgetSpan(
+ alignment: PlaceholderAlignment.top,
+ baseline: TextBaseline.alphabetic,
+ child: Checkbox(value: true, onChanged: null),
+ ),
+ WidgetSpan(
+ child: Checkbox(value: false, onChanged: null),
+ ),
+ TextSpan(text: 'He ', style: TextStyle(fontSize: 20)),
+ WidgetSpan(
+ alignment: PlaceholderAlignment.top,
+ baseline: TextBaseline.alphabetic,
+ child: SizedBox(
+ width: 50.0,
+ height: 55.0,
+ child: DecoratedBox(
+ decoration: BoxDecoration(
+ color: Color(0xffffff00),
+ ),
+ child: Center(
+ child:SizedBox(
+ width: 10.0,
+ height: 15.0,
+ child: DecoratedBox(
+ decoration: BoxDecoration(
+ color: Color(0xffff0000),
+ ),
),
),
),
),
),
),
- ),
- TextSpan(text: 'hello world! seize the day!'),
- WidgetSpan(
- alignment: PlaceholderAlignment.top,
- baseline: TextBaseline.alphabetic,
- child: Checkbox(value: false, onChanged: null),
- ),
- WidgetSpan(
- alignment: PlaceholderAlignment.top,
- baseline: TextBaseline.alphabetic,
- child: SizedBox(
- width: 20,
- height: 20,
- child: Checkbox(value: true, onChanged: null),
+ TextSpan(text: 'hello world! seize the day!'),
+ WidgetSpan(
+ alignment: PlaceholderAlignment.top,
+ baseline: TextBaseline.alphabetic,
+ child: Checkbox(value: false, onChanged: null),
),
- ),
- WidgetSpan(
- alignment: PlaceholderAlignment.top,
- baseline: TextBaseline.alphabetic,
- child: Checkbox(value: false, onChanged: null),
- ),
- WidgetSpan(
- alignment: PlaceholderAlignment.top,
- baseline: TextBaseline.alphabetic,
- child: SizedBox(
- width: 20,
- height: 20,
- child: Checkbox(value: true, onChanged: null),
+ WidgetSpan(
+ alignment: PlaceholderAlignment.top,
+ baseline: TextBaseline.alphabetic,
+ child: SizedBox(
+ width: 20,
+ height: 20,
+ child: Checkbox(value: true, onChanged: null),
+ ),
),
- ),
- WidgetSpan(
- alignment: PlaceholderAlignment.top,
- baseline: TextBaseline.alphabetic,
- child: Text('embedded'),
- ),
- TextSpan(text: 'ref'),
- ],
+ WidgetSpan(
+ alignment: PlaceholderAlignment.top,
+ baseline: TextBaseline.alphabetic,
+ child: Checkbox(value: false, onChanged: null),
+ ),
+ WidgetSpan(
+ alignment: PlaceholderAlignment.top,
+ baseline: TextBaseline.alphabetic,
+ child: SizedBox(
+ width: 20,
+ height: 20,
+ child: Checkbox(value: true, onChanged: null),
+ ),
+ ),
+ WidgetSpan(
+ alignment: PlaceholderAlignment.top,
+ baseline: TextBaseline.alphabetic,
+ child: Text('embedded'),
+ ),
+ TextSpan(text: 'ref'),
+ ],
+ ),
+ textDirection: TextDirection.ltr,
),
- textDirection: TextDirection.ltr,
),
),
),
@@ -1216,97 +1231,100 @@
testWidgets('Text Inline widget middle', (WidgetTester tester) async {
await tester.pumpWidget(
- Center(
- child: RepaintBoundary(
- child: Material(
- child: Directionality(
- textDirection: TextDirection.ltr,
- child: Container(
- width: 400.0,
- height: 200.0,
- decoration: const BoxDecoration(
- color: Color(0xff00ff00),
- ),
- child: ConstrainedBox(
- constraints: const BoxConstraints(maxWidth: 200, maxHeight: 100),
- child: const Text.rich(
- TextSpan(
- text: 'C ',
- style: TextStyle(
- fontSize: 16,
- ),
- children: <InlineSpan>[
- WidgetSpan(
- alignment: PlaceholderAlignment.middle,
- baseline: TextBaseline.alphabetic,
- child: Checkbox(value: true, onChanged: null),
+ Theme(
+ data: ThemeData(useMaterial3: false),
+ child: Center(
+ child: RepaintBoundary(
+ child: Material(
+ child: Directionality(
+ textDirection: TextDirection.ltr,
+ child: Container(
+ width: 400.0,
+ height: 200.0,
+ decoration: const BoxDecoration(
+ color: Color(0xff00ff00),
+ ),
+ child: ConstrainedBox(
+ constraints: const BoxConstraints(maxWidth: 200, maxHeight: 100),
+ child: const Text.rich(
+ TextSpan(
+ text: 'C ',
+ style: TextStyle(
+ fontSize: 16,
),
- WidgetSpan(
- child: Checkbox(value: false, onChanged: null),
- ),
- TextSpan(text: 'He ', style: TextStyle(fontSize: 20)),
- WidgetSpan(
- alignment: PlaceholderAlignment.middle,
- baseline: TextBaseline.alphabetic,
- child: SizedBox(
- width: 50.0,
- height: 55.0,
- child: DecoratedBox(
- decoration: BoxDecoration(
- color: Color(0xffffff00),
- ),
- child: Center(
- child:SizedBox(
- width: 10.0,
- height: 15.0,
- child: DecoratedBox(
- decoration: BoxDecoration(
- color: Color(0xffff0000),
+ children: <InlineSpan>[
+ WidgetSpan(
+ alignment: PlaceholderAlignment.middle,
+ baseline: TextBaseline.alphabetic,
+ child: Checkbox(value: true, onChanged: null),
+ ),
+ WidgetSpan(
+ child: Checkbox(value: false, onChanged: null),
+ ),
+ TextSpan(text: 'He ', style: TextStyle(fontSize: 20)),
+ WidgetSpan(
+ alignment: PlaceholderAlignment.middle,
+ baseline: TextBaseline.alphabetic,
+ child: SizedBox(
+ width: 50.0,
+ height: 55.0,
+ child: DecoratedBox(
+ decoration: BoxDecoration(
+ color: Color(0xffffff00),
+ ),
+ child: Center(
+ child:SizedBox(
+ width: 10.0,
+ height: 15.0,
+ child: DecoratedBox(
+ decoration: BoxDecoration(
+ color: Color(0xffff0000),
+ ),
),
),
),
),
),
),
- ),
- TextSpan(text: 'hello world! seize the day!'),
- WidgetSpan(
- alignment: PlaceholderAlignment.middle,
- baseline: TextBaseline.alphabetic,
- child: Checkbox(value: false, onChanged: null),
- ),
- WidgetSpan(
- alignment: PlaceholderAlignment.middle,
- baseline: TextBaseline.alphabetic,
- child: SizedBox(
- width: 20,
- height: 20,
- child: Checkbox(value: true, onChanged: null),
+ TextSpan(text: 'hello world! seize the day!'),
+ WidgetSpan(
+ alignment: PlaceholderAlignment.middle,
+ baseline: TextBaseline.alphabetic,
+ child: Checkbox(value: false, onChanged: null),
),
- ),
- WidgetSpan(
- alignment: PlaceholderAlignment.middle,
- baseline: TextBaseline.alphabetic,
- child: Checkbox(value: false, onChanged: null),
- ),
- WidgetSpan(
- alignment: PlaceholderAlignment.middle,
- baseline: TextBaseline.alphabetic,
- child: SizedBox(
- width: 20,
- height: 20,
- child: Checkbox(value: true, onChanged: null),
+ WidgetSpan(
+ alignment: PlaceholderAlignment.middle,
+ baseline: TextBaseline.alphabetic,
+ child: SizedBox(
+ width: 20,
+ height: 20,
+ child: Checkbox(value: true, onChanged: null),
+ ),
),
- ),
- WidgetSpan(
- alignment: PlaceholderAlignment.middle,
- baseline: TextBaseline.alphabetic,
- child: Text('embedded'),
- ),
- TextSpan(text: 'ref'),
- ],
+ WidgetSpan(
+ alignment: PlaceholderAlignment.middle,
+ baseline: TextBaseline.alphabetic,
+ child: Checkbox(value: false, onChanged: null),
+ ),
+ WidgetSpan(
+ alignment: PlaceholderAlignment.middle,
+ baseline: TextBaseline.alphabetic,
+ child: SizedBox(
+ width: 20,
+ height: 20,
+ child: Checkbox(value: true, onChanged: null),
+ ),
+ ),
+ WidgetSpan(
+ alignment: PlaceholderAlignment.middle,
+ baseline: TextBaseline.alphabetic,
+ child: Text('embedded'),
+ ),
+ TextSpan(text: 'ref'),
+ ],
+ ),
+ textDirection: TextDirection.ltr,
),
- textDirection: TextDirection.ltr,
),
),
),
diff --git a/packages/flutter/test/widgets/text_test.dart b/packages/flutter/test/widgets/text_test.dart
index c273342..ea32025 100644
--- a/packages/flutter/test/widgets/text_test.dart
+++ b/packages/flutter/test/widgets/text_test.dart
@@ -208,6 +208,7 @@
double textScaleFactor = 1.0;
await tester.pumpWidget(
MaterialApp(
+ theme: ThemeData(useMaterial3: false),
home: Scaffold(
appBar: AppBar(title: const Text('title')),
body: Center(
@@ -236,6 +237,7 @@
textScaleFactor = textScaleFactor * 5;
await tester.pumpWidget(
MaterialApp(
+ theme: ThemeData(useMaterial3: false),
home: Scaffold(
appBar: AppBar(title: const Text('title')),
body: Center(
@@ -1132,6 +1134,7 @@
Future<void> createText(TextWidthBasis textWidthBasis) {
return tester.pumpWidget(
MaterialApp(
+ theme: ThemeData(useMaterial3: false),
home: Scaffold(
body: Center(
// Each word takes up more than a half of a line. Together they
diff --git a/packages/flutter/test/widgets/two_dimensional_utils.dart b/packages/flutter/test/widgets/two_dimensional_utils.dart
index f9da5ab..5eb3bf2 100644
--- a/packages/flutter/test/widgets/two_dimensional_utils.dart
+++ b/packages/flutter/test/widgets/two_dimensional_utils.dart
@@ -46,6 +46,7 @@
bool setLayoutOffset = true,
}) {
return MaterialApp(
+ theme: ThemeData(useMaterial3: false),
restorationScopeId: restorationID,
home: Scaffold(
body: SimpleBuilderTableView(
diff --git a/packages/flutter/test/widgets/widget_inspector_test.dart b/packages/flutter/test/widgets/widget_inspector_test.dart
index aa64ca4..a75293e 100644
--- a/packages/flutter/test/widgets/widget_inspector_test.dart
+++ b/packages/flutter/test/widgets/widget_inspector_test.dart
@@ -19,6 +19,7 @@
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';
+import 'package:leak_tracker/leak_tracker.dart';
import 'widget_inspector_test_utils.dart';
@@ -240,7 +241,41 @@
}
}
+final List<Object> _weakValueTests = <Object>[1, 1.0, 'hello', true, false, Object(), <int>[3, 4], DateTime(2023)];
+
void main() {
+ group('$InspectorReferenceData', (){
+ for (final Object item in _weakValueTests) {
+ test('can be created for any type but $Record, $item', () async {
+ final InspectorReferenceData weakValue = InspectorReferenceData(item, 'id');
+ expect(weakValue.value, item);
+ });
+ }
+
+ test('throws for $Record', () async {
+ expect(()=> InspectorReferenceData((1, 2), 'id'), throwsA(isA<ArgumentError>()));
+ });
+ });
+
+ group('$WeakMap', (){
+ for (final Object item in _weakValueTests) {
+ test('assigns and removes value, $item', () async {
+ final WeakMap<Object, Object> weakMap = WeakMap<Object, Object>();
+ weakMap[item] = 1;
+ expect(weakMap[item], 1);
+ expect(weakMap.remove(item), 1);
+ expect(weakMap[item], null);
+ });
+ }
+
+ for (final Object item in _weakValueTests) {
+ test('returns null for absent value, $item', () async {
+ final WeakMap<Object, Object> weakMap = WeakMap<Object, Object>();
+ expect(weakMap[item], null);
+ });
+ }
+ });
+
_TestWidgetInspectorService.runTests();
}
@@ -261,6 +296,25 @@
}
});
+ test ('objectToDiagnosticsNode returns null for non-diagnosticable', () {
+ expect(WidgetInspectorService.objectToDiagnosticsNode(Alignment.bottomCenter), isNull);
+ });
+
+ test('WidgetInspector does not hold objects from GC', () async {
+ List<DateTime>? someObject = <DateTime>[DateTime.now(), DateTime.now()];
+ final String? id = service.toId(someObject, 'group_name');
+
+ expect(id, isNotNull);
+
+ final WeakReference<Object> ref = WeakReference<Object>(someObject);
+ someObject = null;
+
+ // 1 should be enough for [fullGcCycles], but it is 3 to make sure tests are not flaky.
+ await forceGC(fullGcCycles: 3);
+
+ expect(ref.target, null);
+ });
+
testWidgets('WidgetInspector smoke test', (WidgetTester tester) async {
// This is a smoke test to verify that adding the inspector doesn't crash.
await tester.pumpWidget(
@@ -878,7 +932,6 @@
expect(chainNode['node'], isMap);
final Map<String, Object?> jsonNode = chainNode['node']! as Map<String, Object?>;
expect(service.toObject(jsonNode['valueId']! as String), equals(element));
- expect(service.toObject(jsonNode['objectId']! as String), isA<DiagnosticsNode>());
expect(chainNode['children'], isList);
final List<Object?> jsonChildren = chainNode['children']! as List<Object?>;
@@ -894,24 +947,22 @@
expect(jsonChildren[j], isMap);
final Map<String, Object?> childJson = jsonChildren[j]! as Map<String, Object?>;
expect(service.toObject(childJson['valueId']! as String), equals(childrenElements[j]));
- expect(service.toObject(childJson['objectId']! as String), isA<DiagnosticsNode>());
}
}
});
test('WidgetInspectorService getProperties', () {
- final DiagnosticsNode diagnostic = const Text('a', textDirection: TextDirection.ltr).toDiagnosticsNode();
+ const Diagnosticable diagnosticable = Text('a', textDirection: TextDirection.ltr);
const String group = 'group';
service.disposeAllGroups();
- final String id = service.toId(diagnostic, group)!;
+ final String id = service.toId(diagnosticable, group)!;
final List<Object?> propertiesJson = json.decode(service.getProperties(id, group)) as List<Object?>;
- final List<DiagnosticsNode> properties = diagnostic.getProperties();
+ final List<DiagnosticsNode> properties = diagnosticable.toDiagnosticsNode().getProperties();
expect(properties, isNotEmpty);
expect(propertiesJson.length, equals(properties.length));
for (int i = 0; i < propertiesJson.length; ++i) {
final Map<String, Object?> propertyJson = propertiesJson[i]! as Map<String, Object?>;
expect(service.toObject(propertyJson['valueId'] as String?), equals(properties[i].value));
- expect(service.toObject(propertyJson['objectId']! as String), isA<DiagnosticsNode>());
}
});
@@ -940,7 +991,6 @@
for (int i = 0; i < propertiesJson.length; ++i) {
final Map<String, Object?> propertyJson = propertiesJson[i]! as Map<String, Object?>;
expect(service.toObject(propertyJson['valueId']! as String), equals(children[i].value));
- expect(service.toObject(propertyJson['objectId']! as String), isA<DiagnosticsNode>());
}
});
@@ -2086,7 +2136,6 @@
expect(chainNode['node'], isMap);
final Map<String, Object?> jsonNode = chainNode['node']! as Map<String, Object?>;
expect(service.toObject(jsonNode['valueId']! as String), equals(element));
- expect(service.toObject(jsonNode['objectId']! as String), isA<DiagnosticsNode>());
expect(chainNode['children'], isList);
final List<Object?> jsonChildren = chainNode['children']! as List<Object?>;
@@ -2102,26 +2151,24 @@
expect(jsonChildren[j], isMap);
final Map<String, Object?> childJson = jsonChildren[j]! as Map<String, Object?>;
expect(service.toObject(childJson['valueId']! as String), equals(childrenElements[j]));
- expect(service.toObject(childJson['objectId']! as String), isA<DiagnosticsNode>());
}
}
});
test('ext.flutter.inspector.getProperties', () async {
- final DiagnosticsNode diagnostic = const Text('a', textDirection: TextDirection.ltr).toDiagnosticsNode();
+ const Diagnosticable diagnosticable = Text('a', textDirection: TextDirection.ltr);
const String group = 'group';
- final String id = service.toId(diagnostic, group)!;
+ final String id = service.toId(diagnosticable, group)!;
final List<Object?> propertiesJson = (await service.testExtension(
WidgetInspectorServiceExtensions.getProperties.name,
<String, String>{'arg': id, 'objectGroup': group},
))! as List<Object?>;
- final List<DiagnosticsNode> properties = diagnostic.getProperties();
+ final List<DiagnosticsNode> properties = diagnosticable.toDiagnosticsNode().getProperties();
expect(properties, isNotEmpty);
expect(propertiesJson.length, equals(properties.length));
for (int i = 0; i < propertiesJson.length; ++i) {
final Map<String, Object?> propertyJson = propertiesJson[i]! as Map<String, Object?>;
expect(service.toObject(propertyJson['valueId'] as String?), equals(properties[i].value));
- expect(service.toObject(propertyJson['objectId']! as String), isA<DiagnosticsNode>());
}
});
@@ -2152,7 +2199,6 @@
for (int i = 0; i < propertiesJson.length; ++i) {
final Map<String, Object?> propertyJson = propertiesJson[i]! as Map<String, Object?>;
expect(service.toObject(propertyJson['valueId']! as String), equals(children[i].value));
- expect(service.toObject(propertyJson['objectId']! as String), isA<DiagnosticsNode>());
}
});
@@ -2171,26 +2217,26 @@
),
),
);
- final DiagnosticsNode diagnostic = find.byType(Stack).evaluate().first.toDiagnosticsNode();
- final String id = service.toId(diagnostic, group)!;
+ final Diagnosticable diagnosticable = find.byType(Stack).evaluate().first;
+ final String id = service.toId(diagnosticable, group)!;
final List<Object?> childrenJson = (await service.testExtension(
WidgetInspectorServiceExtensions.getChildrenDetailsSubtree.name,
<String, String>{'arg': id, 'objectGroup': group},
))! as List<Object?>;
- final List<DiagnosticsNode> children = diagnostic.getChildren();
+ final List<DiagnosticsNode> children = diagnosticable.toDiagnosticsNode().getChildren();
expect(children.length, equals(3));
expect(childrenJson.length, equals(children.length));
for (int i = 0; i < childrenJson.length; ++i) {
final Map<String, Object?> childJson = childrenJson[i]! as Map<String, Object?>;
expect(service.toObject(childJson['valueId']! as String), equals(children[i].value));
- expect(service.toObject(childJson['objectId']! as String), isA<DiagnosticsNode>());
final List<Object?> propertiesJson = childJson['properties']! as List<Object?>;
- final DiagnosticsNode diagnosticsNode = service.toObject(childJson['objectId']! as String)! as DiagnosticsNode;
- final List<DiagnosticsNode> expectedProperties = diagnosticsNode.getProperties();
+ final Element element = service.toObject(childJson['valueId']! as String)! as Element;
+ final List<DiagnosticsNode> expectedProperties = element.toDiagnosticsNode().getProperties();
+ final Iterable<Object?> propertyValues = expectedProperties.map((DiagnosticsNode e) => e.value.toString());
for (final Map<String, Object?> propertyJson in propertiesJson.cast<Map<String, Object?>>()) {
- final Object? property = service.toObject(propertyJson['objectId']! as String);
- expect(property, isA<DiagnosticsNode>());
- expect(expectedProperties, contains(property));
+ final String id = propertyJson['valueId']! as String;
+ final String property = service.toObject(id)!.toString();
+ expect(propertyValues, contains(property));
}
}
});
@@ -2210,31 +2256,31 @@
),
),
);
- final DiagnosticsNode diagnostic = find.byType(Stack).evaluate().first.toDiagnosticsNode();
- final String id = service.toId(diagnostic, group)!;
+ final Diagnosticable diagnosticable = find.byType(Stack).evaluate().first;
+ final String id = service.toId(diagnosticable, group)!;
final Map<String, Object?> subtreeJson = (await service.testExtension(
WidgetInspectorServiceExtensions.getDetailsSubtree.name,
<String, String>{'arg': id, 'objectGroup': group},
))! as Map<String, Object?>;
- expect(subtreeJson['objectId'], equals(id));
+ expect(subtreeJson['valueId'], equals(id));
final List<Object?> childrenJson = subtreeJson['children']! as List<Object?>;
- final List<DiagnosticsNode> children = diagnostic.getChildren();
+ final List<DiagnosticsNode> children = diagnosticable.toDiagnosticsNode().getChildren();
expect(children.length, equals(3));
expect(childrenJson.length, equals(children.length));
for (int i = 0; i < childrenJson.length; ++i) {
final Map<String, Object?> childJson = childrenJson[i]! as Map<String, Object?>;
expect(service.toObject(childJson['valueId']! as String), equals(children[i].value));
- expect(service.toObject(childJson['objectId']! as String), isA<DiagnosticsNode>());
final List<Object?> propertiesJson = childJson['properties']! as List<Object?>;
for (final Map<String, Object?> propertyJson in propertiesJson.cast<Map<String, Object?>>()) {
expect(propertyJson, isNot(contains('children')));
}
- final DiagnosticsNode diagnosticsNode = service.toObject(childJson['objectId']! as String)! as DiagnosticsNode;
- final List<DiagnosticsNode> expectedProperties = diagnosticsNode.getProperties();
+ final Element element = service.toObject(childJson['valueId']! as String)! as Element;
+ final List<DiagnosticsNode> expectedProperties = element.toDiagnosticsNode().getProperties();
+ final Iterable<Object?> propertyValues = expectedProperties.map((DiagnosticsNode e) => e.value.toString());
for (final Map<String, Object?> propertyJson in propertiesJson.cast<Map<String, Object?>>()) {
- final Object property = service.toObject(propertyJson['objectId']! as String)!;
- expect(property, isA<DiagnosticsNode>());
- expect(expectedProperties, contains(property));
+ final String id = propertyJson['valueId']! as String;
+ final String property = service.toObject(id)!.toString();
+ expect(propertyValues, contains(property));
}
}
@@ -2259,13 +2305,12 @@
a.children.add(b.toDiagnosticsNode());
b.related = a;
- final DiagnosticsNode diagnostic = a.toDiagnosticsNode();
- final String id = service.toId(diagnostic, group)!;
+ final String id = service.toId(a, group)!;
final Map<String, Object?> subtreeJson = (await service.testExtension(
WidgetInspectorServiceExtensions.getDetailsSubtree.name,
<String, String>{'arg': id, 'objectGroup': group},
))! as Map<String, Object?>;
- expect(subtreeJson['objectId'], equals(id));
+ expect(subtreeJson['valueId'], equals(id));
expect(subtreeJson, contains('children'));
final List<Object?> propertiesJson = subtreeJson['properties']! as List<Object?>;
expect(propertiesJson.length, equals(1));
@@ -2290,7 +2335,6 @@
testWidgets('ext.flutter.inspector.getRootWidgetSummaryTree', (WidgetTester tester) async {
const String group = 'test-group';
-
await tester.pumpWidget(
const Directionality(
textDirection: TextDirection.ltr,
@@ -2303,6 +2347,7 @@
),
),
);
+
final Element elementA = find.text('a').evaluate().first;
service.disposeAllGroups();
@@ -2318,6 +2363,7 @@
WidgetInspectorServiceExtensions.getRootWidgetSummaryTree.name,
<String, String>{'objectGroup': group},
))! as Map<String, Object?>;
+
// We haven't yet properly specified which directories are summary tree
// directories so we get an empty tree other than the root that is always
// included.
@@ -2353,7 +2399,7 @@
List<Object?> alternateChildrenJson = (await service.testExtension(
WidgetInspectorServiceExtensions.getChildrenSummaryTree.name,
- <String, String>{'arg': rootJson['objectId']! as String, 'objectGroup': group},
+ <String, String>{'arg': rootJson['valueId']! as String, 'objectGroup': group},
))! as List<Object?>;
expect(alternateChildrenJson.length, equals(1));
Map<String, Object?> childJson = childrenJson[0]! as Map<String, Object?>;
@@ -2365,7 +2411,7 @@
childrenJson = childJson['children']! as List<Object?>;
alternateChildrenJson = (await service.testExtension(
WidgetInspectorServiceExtensions.getChildrenSummaryTree.name,
- <String, String>{'arg': childJson['objectId']! as String, 'objectGroup': group},
+ <String, String>{'arg': childJson['valueId']! as String, 'objectGroup': group},
))! as List<Object?>;
expect(alternateChildrenJson.length, equals(1));
expect(childrenJson.length, equals(1));
@@ -2379,7 +2425,7 @@
childrenJson = childJson['children']! as List<Object?>;
alternateChildrenJson = (await service.testExtension(
WidgetInspectorServiceExtensions.getChildrenSummaryTree.name,
- <String, String>{'arg': childJson['objectId']! as String, 'objectGroup': group},
+ <String, String>{'arg': childJson['valueId']! as String, 'objectGroup': group},
))! as List<Object?>;
expect(alternateChildrenJson.length, equals(3));
expect(childrenJson.length, equals(3));
@@ -2390,7 +2436,7 @@
expect(alternateChildJson['valueId'], equals(childJson['valueId']));
alternateChildrenJson = (await service.testExtension(
WidgetInspectorServiceExtensions.getChildrenSummaryTree.name,
- <String, String>{'arg': childJson['objectId']! as String, 'objectGroup': group},
+ <String, String>{'arg': childJson['valueId']! as String, 'objectGroup': group},
))! as List<Object?>;
expect(alternateChildrenJson.length , equals(0));
// Tests are failing when this typo is fixed.
@@ -2449,7 +2495,7 @@
List<Object?> alternateChildrenJson = (await service.testExtension(
WidgetInspectorServiceExtensions.getChildrenSummaryTree.name,
- <String, String>{'arg': rootJson['objectId']! as String, 'objectGroup': group},
+ <String, String>{'arg': rootJson['valueId']! as String, 'objectGroup': group},
))! as List<Object?>;
expect(alternateChildrenJson.length, equals(1));
Map<String, Object?> childJson = childrenJson[0]! as Map<String, Object?>;
@@ -2461,7 +2507,7 @@
childrenJson = childJson['children']! as List<Object?>;
alternateChildrenJson = (await service.testExtension(
WidgetInspectorServiceExtensions.getChildrenSummaryTree.name,
- <String, String>{'arg': childJson['objectId']! as String, 'objectGroup': group},
+ <String, String>{'arg': childJson['valueId']! as String, 'objectGroup': group},
))! as List<Object?>;
expect(alternateChildrenJson.length, equals(1));
expect(childrenJson.length, equals(1));
@@ -2475,7 +2521,7 @@
childrenJson = childJson['children']! as List<Object?>;
alternateChildrenJson = (await service.testExtension(
WidgetInspectorServiceExtensions.getChildrenSummaryTree.name,
- <String, String>{'arg': childJson['objectId']! as String, 'objectGroup': group},
+ <String, String>{'arg': childJson['valueId']! as String, 'objectGroup': group},
))! as List<Object?>;
expect(alternateChildrenJson.length, equals(3));
expect(childrenJson.length, equals(3));
@@ -3745,7 +3791,7 @@
_CreationLocation location = knownLocations[id]!;
expect(location.file, equals(file));
// ClockText widget.
- expect(location.line, equals(55));
+ expect(location.line, equals(56));
expect(location.column, equals(9));
expect(location.name, equals('ClockText'));
expect(count, equals(1));
@@ -3755,7 +3801,7 @@
location = knownLocations[id]!;
expect(location.file, equals(file));
// Text widget in _ClockTextState build method.
- expect(location.line, equals(93));
+ expect(location.line, equals(94));
expect(location.column, equals(12));
expect(location.name, equals('Text'));
expect(count, equals(1));
@@ -3782,7 +3828,7 @@
location = knownLocations[id]!;
expect(location.file, equals(file));
// ClockText widget.
- expect(location.line, equals(55));
+ expect(location.line, equals(56));
expect(location.column, equals(9));
expect(location.name, equals('ClockText'));
expect(count, equals(3)); // 3 clock widget instances rebuilt.
@@ -3792,7 +3838,7 @@
location = knownLocations[id]!;
expect(location.file, equals(file));
// Text widget in _ClockTextState build method.
- expect(location.line, equals(93));
+ expect(location.line, equals(94));
expect(location.column, equals(12));
expect(location.name, equals('Text'));
expect(count, equals(3)); // 3 clock widget instances rebuilt.
@@ -4382,8 +4428,7 @@
final Element rowElement = tester.element(find.byType(Row));
service.setSelection(rowElement, group);
- final DiagnosticsNode diagnostic = rowElement.toDiagnosticsNode();
- final String id = service.toId(diagnostic, group)!;
+ final String id = service.toId(rowElement, group)!;
final Map<String, Object?> result = (await service.testExtension(
WidgetInspectorServiceExtensions.getLayoutExplorerNode.name,
<String, String>{'id': id, 'groupName': group, 'subtreeDepth': '1'},
@@ -4428,8 +4473,7 @@
final Element flexibleElement = tester.element(find.byType(Flexible).first);
service.setSelection(flexibleElement, group);
- final DiagnosticsNode diagnostic = flexibleElement.toDiagnosticsNode();
- final String id = service.toId(diagnostic, group)!;
+ final String id = service.toId(flexibleElement, group)!;
final Map<String, Object?> result = (await service.testExtension(
WidgetInspectorServiceExtensions.getLayoutExplorerNode.name,
<String, String>{'id': id, 'groupName': group, 'subtreeDepth': '1'},
@@ -4470,16 +4514,14 @@
await pumpWidgetForLayoutExplorer(tester);
final Element element = tester.element(find.byType(Directionality).first);
- Element? root;
+ late Element root;
element.visitAncestorElements((Element ancestor) {
root = ancestor;
return true;
});
- expect(root, isNotNull);
service.setSelection(root, group);
- final DiagnosticsNode diagnostic = root!.toDiagnosticsNode();
- final String id = service.toId(diagnostic, group)!;
+ final String id = service.toId(root, group)!;
final Map<String, Object?> result = (await service.testExtension(
WidgetInspectorServiceExtensions.getLayoutExplorerNode.name,
<String, String>{'id': id, 'groupName': group, 'subtreeDepth': '1'},
@@ -4510,8 +4552,7 @@
final Element childElement = tester.element(find.byType(Flexible).first);
service.setSelection(childElement, group);
- final DiagnosticsNode diagnostic = childElement.toDiagnosticsNode();
- final String id = service.toId(diagnostic, group)!;
+ final String id = service.toId(childElement, group)!;
Map<String, Object?> result = (await service.testExtension(
WidgetInspectorServiceExtensions.getLayoutExplorerNode.name,
<String, String>{'id': id, 'groupName': group, 'subtreeDepth': '1'},
@@ -4541,8 +4582,7 @@
final Element childElement = tester.element(find.byType(Flexible).first);
service.setSelection(childElement, group);
- final DiagnosticsNode diagnostic = childElement.toDiagnosticsNode();
- final String id = service.toId(diagnostic, group)!;
+ final String id = service.toId(childElement, group)!;
Map<String, Object?> result = (await service.testExtension(
WidgetInspectorServiceExtensions.getLayoutExplorerNode.name,
<String, String>{'id': id, 'groupName': group, 'subtreeDepth': '1'},
@@ -4572,8 +4612,7 @@
final Element rowElement = tester.element(find.byType(Row).first);
service.setSelection(rowElement, group);
- final DiagnosticsNode diagnostic = rowElement.toDiagnosticsNode();
- final String id = service.toId(diagnostic, group)!;
+ final String id = service.toId(rowElement, group)!;
Map<String, Object?> result = (await service.testExtension(
WidgetInspectorServiceExtensions.getLayoutExplorerNode.name,
<String, String>{'id': id, 'groupName': group, 'subtreeDepth': '1'},
@@ -4985,7 +5024,7 @@
final List<Object?> childrenOfMaterialApp = (childrenOfRoot.first! as Map<String, Object?>)['children']! as List<Object?>;
final Map<String, Object?> scaffold = childrenOfMaterialApp.first! as Map<String, Object?>;
expect(scaffold['description'], 'Scaffold');
- final String objectId = scaffold['objectId']! as String;
+ final String objectId = scaffold['valueId']! as String;
final String details = service.getDetailsSubtree(objectId, 'foo2');
// ignore: avoid_dynamic_calls
final List<Object?> detailedChildren = json.decode(details)['children'] as List<Object?>;
diff --git a/packages/flutter/test_fixes/services/services.dart b/packages/flutter/test_fixes/services/services.dart
index 6e171fc..bbb5250 100644
--- a/packages/flutter/test_fixes/services/services.dart
+++ b/packages/flutter/test_fixes/services/services.dart
@@ -5,6 +5,10 @@
import 'package:flutter/services.dart';
void main() {
+ // Changes made in https://github.com/flutter/flutter/pull/122446
+ final clipboardData1 = ClipboardData();
+ final clipboardData2 = ClipboardData(text: null);
+
// Changes made in https://github.com/flutter/flutter/pull/60320
final SurfaceAndroidViewController surfaceController = SurfaceAndroidViewController(
viewId: 10,
diff --git a/packages/flutter/test_fixes/services/services.dart.expect b/packages/flutter/test_fixes/services/services.dart.expect
index 7a69dc5..469d500 100644
--- a/packages/flutter/test_fixes/services/services.dart.expect
+++ b/packages/flutter/test_fixes/services/services.dart.expect
@@ -5,6 +5,10 @@
import 'package:flutter/services.dart';
void main() {
+ // Changes made in https://github.com/flutter/flutter/pull/122446
+ final clipboardData1 = ClipboardData(text: '');
+ final clipboardData2 = ClipboardData(text: '');
+
// Changes made in https://github.com/flutter/flutter/pull/60320
final SurfaceAndroidViewController surfaceController = SurfaceAndroidViewController(
viewId: 10,
diff --git a/packages/flutter/test_private/bin/test_private.dart b/packages/flutter/test_private/bin/test_private.dart
index 25b89f3..372ddb6 100644
--- a/packages/flutter/test_private/bin/test_private.dart
+++ b/packages/flutter/test_private/bin/test_private.dart
@@ -195,7 +195,13 @@
// Use Flutter's analysis_options.yaml file from packages/flutter.
File(path.join(tmpdir.absolute.path, 'analysis_options.yaml'))
- .writeAsStringSync('include: ${path.toUri(path.join(flutterRoot.path, 'packages', 'flutter', 'analysis_options.yaml'))}');
+ .writeAsStringSync(
+ 'include: ${path.toUri(path.join(flutterRoot.path, 'packages', 'flutter', 'analysis_options.yaml'))}\n'
+ 'linter:\n'
+ ' rules:\n'
+ // The code does wonky things with the part-of directive that cause false positives.
+ ' unreachable_from_main: false'
+ );
return true;
}
diff --git a/packages/flutter/test_private/test/pubspec.yaml b/packages/flutter/test_private/test/pubspec.yaml
index 3e4d477..dbdcd86 100644
--- a/packages/flutter/test_private/test/pubspec.yaml
+++ b/packages/flutter/test_private/test/pubspec.yaml
@@ -19,16 +19,16 @@
async: 2.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
clock: 1.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
matcher: 0.12.16 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path: 1.8.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
flutter_goldens:
@@ -39,4 +39,4 @@
platform: 3.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
process: 4.2.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
-# PUBSPEC CHECKSUM: ac19
+# PUBSPEC CHECKSUM: 3540
diff --git a/packages/flutter_driver/lib/src/common/handler_factory.dart b/packages/flutter_driver/lib/src/common/handler_factory.dart
index def0c66..05e70ae 100644
--- a/packages/flutter_driver/lib/src/common/handler_factory.dart
+++ b/packages/flutter_driver/lib/src/common/handler_factory.dart
@@ -320,7 +320,7 @@
SemanticsNode? node;
while (renderObject != null && node == null) {
node = renderObject.debugSemantics;
- renderObject = renderObject.parent as RenderObject?;
+ renderObject = renderObject.parent;
}
if (node == null) {
throw StateError('No semantics data found');
diff --git a/packages/flutter_driver/pubspec.yaml b/packages/flutter_driver/pubspec.yaml
index ba8dd2a..15e98d5 100644
--- a/packages/flutter_driver/pubspec.yaml
+++ b/packages/flutter_driver/pubspec.yaml
@@ -15,7 +15,7 @@
sdk: flutter
path: 1.8.3
meta: 1.9.1
- vm_service: 11.6.0
+ vm_service: 11.7.2
webdriver: 3.0.2
async: 2.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -23,35 +23,37 @@
characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
clock: 1.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
collection: 1.17.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
matcher: 0.12.16 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
platform: 3.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
process: 4.2.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
sync_http: 0.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
fake_async: 1.3.1
- test: 1.24.3
+ test: 1.24.4
- _fe_analyzer_shared: 61.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- analyzer: 5.13.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ _fe_analyzer_shared: 62.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ analyzer: 6.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
args: 2.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
convert: 3.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
coverage: 1.6.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
crypto: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ dart_internal: 0.2.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
frontend_server_client: 3.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
glob: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http_multi_server: 3.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http_parser: 4.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
io: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
logging: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
mime: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
node_preamble: 2.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -64,11 +66,11 @@
shelf_web_socket: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_map_stack_trace: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_maps: 0.10.12 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_core: 0.5.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_core: 0.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
-# PUBSPEC CHECKSUM: 163d
+# PUBSPEC CHECKSUM: 6927
diff --git a/packages/flutter_goldens/pubspec.yaml b/packages/flutter_goldens/pubspec.yaml
index 51e3ff6..ad47b7a 100644
--- a/packages/flutter_goldens/pubspec.yaml
+++ b/packages/flutter_goldens/pubspec.yaml
@@ -23,17 +23,17 @@
collection: 1.17.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
crypto: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
fake_async: 1.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
matcher: 0.12.16 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path: 1.8.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
-# PUBSPEC CHECKSUM: dc7a
+# PUBSPEC CHECKSUM: 99a1
diff --git a/packages/flutter_localizations/lib/src/l10n/generated_material_localizations.dart b/packages/flutter_localizations/lib/src/l10n/generated_material_localizations.dart
index d575829..d936427 100644
--- a/packages/flutter_localizations/lib/src/l10n/generated_material_localizations.dart
+++ b/packages/flutter_localizations/lib/src/l10n/generated_material_localizations.dart
@@ -417,6 +417,9 @@
String get saveButtonLabel => 'Stoor';
@override
+ String get scanTextButtonLabel => 'Skena umbhalo';
+
+ @override
String get scrimLabel => 'Skerm';
@override
@@ -892,6 +895,9 @@
String get saveButtonLabel => 'አስቀምጥ';
@override
+ String get scanTextButtonLabel => 'ጽሑፍ ይቃኙ';
+
+ @override
String get scrimLabel => 'ገዳቢ';
@override
@@ -1367,6 +1373,9 @@
String get saveButtonLabel => 'الحفظ';
@override
+ String get scanTextButtonLabel => 'مسح النص';
+
+ @override
String get scrimLabel => 'تمويه';
@override
@@ -1842,6 +1851,9 @@
String get saveButtonLabel => 'ছেভ কৰক';
@override
+ String get scanTextButtonLabel => 'স্কেন টেক্সট';
+
+ @override
String get scrimLabel => 'স্ক্ৰিম';
@override
@@ -2317,6 +2329,9 @@
String get saveButtonLabel => 'Yadda saxlayın';
@override
+ String get scanTextButtonLabel => 'Mətni skan edin';
+
+ @override
String get scrimLabel => 'Kətan';
@override
@@ -2792,6 +2807,9 @@
String get saveButtonLabel => 'Захаваць';
@override
+ String get scanTextButtonLabel => 'Сканаваць тэкст';
+
+ @override
String get scrimLabel => 'Палатно';
@override
@@ -3267,6 +3285,9 @@
String get saveButtonLabel => 'Запазване';
@override
+ String get scanTextButtonLabel => 'Сканиране на текст';
+
+ @override
String get scrimLabel => 'Скрим';
@override
@@ -3742,6 +3763,9 @@
String get saveButtonLabel => 'সেভ করুন';
@override
+ String get scanTextButtonLabel => 'পাঠ্য স্ক্যান করুন';
+
+ @override
String get scrimLabel => 'স্ক্রিম';
@override
@@ -4217,6 +4241,9 @@
String get saveButtonLabel => 'Sačuvaj';
@override
+ String get scanTextButtonLabel => 'Skeniraj tekst';
+
+ @override
String get scrimLabel => 'Rubno';
@override
@@ -4692,6 +4719,9 @@
String get saveButtonLabel => 'Desa';
@override
+ String get scanTextButtonLabel => 'Escaneja el text';
+
+ @override
String get scrimLabel => 'Fons atenuat';
@override
@@ -5167,6 +5197,9 @@
String get saveButtonLabel => 'Uložit';
@override
+ String get scanTextButtonLabel => 'Naskenujte text';
+
+ @override
String get scrimLabel => 'Scrim';
@override
@@ -5642,6 +5675,9 @@
String get saveButtonLabel => 'Cadw';
@override
+ String get scanTextButtonLabel => 'Scan text';
+
+ @override
String get scrimLabel => 'Scrim';
@override
@@ -6117,6 +6153,9 @@
String get saveButtonLabel => 'Gem';
@override
+ String get scanTextButtonLabel => 'Scan tekst';
+
+ @override
String get scrimLabel => 'Dæmpeskærm';
@override
@@ -6592,6 +6631,9 @@
String get saveButtonLabel => 'Speichern';
@override
+ String get scanTextButtonLabel => 'Text scannen';
+
+ @override
String get scrimLabel => 'Gitter';
@override
@@ -7131,6 +7173,9 @@
String get saveButtonLabel => 'Αποθήκευση';
@override
+ String get scanTextButtonLabel => 'Σάρωση κειμένου';
+
+ @override
String get scrimLabel => 'Επικάλυψη';
@override
@@ -7606,6 +7651,9 @@
String get saveButtonLabel => 'Save';
@override
+ String get scanTextButtonLabel => 'Scan text';
+
+ @override
String get scrimLabel => 'Scrim';
@override
@@ -8815,6 +8863,9 @@
String get saveButtonLabel => 'Guardar';
@override
+ String get scanTextButtonLabel => 'Escanear texto';
+
+ @override
String get scrimLabel => 'Sombreado';
@override
@@ -12673,6 +12724,9 @@
String get saveButtonLabel => 'Salvesta';
@override
+ String get scanTextButtonLabel => 'Skanni teksti';
+
+ @override
String get scrimLabel => 'Sirm';
@override
@@ -13148,6 +13202,9 @@
String get saveButtonLabel => 'Gorde';
@override
+ String get scanTextButtonLabel => 'Eskaneatu testua';
+
+ @override
String get scrimLabel => 'Barrera';
@override
@@ -13623,6 +13680,9 @@
String get saveButtonLabel => 'ذخیره';
@override
+ String get scanTextButtonLabel => 'اسکن متن';
+
+ @override
String get scrimLabel => 'رویه';
@override
@@ -14098,6 +14158,9 @@
String get saveButtonLabel => 'Tallenna';
@override
+ String get scanTextButtonLabel => 'Skannaa tekstiä';
+
+ @override
String get scrimLabel => 'Sermi';
@override
@@ -14573,6 +14636,9 @@
String get saveButtonLabel => 'I-save';
@override
+ String get scanTextButtonLabel => 'I-scan ang text';
+
+ @override
String get scrimLabel => 'Scrim';
@override
@@ -15048,6 +15114,9 @@
String get saveButtonLabel => 'Enregistrer';
@override
+ String get scanTextButtonLabel => 'Numériser du texte';
+
+ @override
String get scrimLabel => 'Fond';
@override
@@ -15665,6 +15734,9 @@
String get saveButtonLabel => 'Gardar';
@override
+ String get scanTextButtonLabel => 'Escanear texto';
+
+ @override
String get scrimLabel => 'Sombreado';
@override
@@ -16140,6 +16212,9 @@
String get saveButtonLabel => 'Speichern';
@override
+ String get scanTextButtonLabel => 'Text scannen';
+
+ @override
String get scrimLabel => 'Gitter';
@override
@@ -16615,6 +16690,9 @@
String get saveButtonLabel => 'સાચવો';
@override
+ String get scanTextButtonLabel => 'ટેક્સ્ટ સ્કેન કરો';
+
+ @override
String get scrimLabel => 'સ્ક્રિમ';
@override
@@ -17090,6 +17168,9 @@
String get saveButtonLabel => 'שמירה';
@override
+ String get scanTextButtonLabel => 'סרוק טקסט';
+
+ @override
String get scrimLabel => 'מיסוך';
@override
@@ -17565,6 +17646,9 @@
String get saveButtonLabel => 'सेव करें';
@override
+ String get scanTextButtonLabel => 'पाठ स्कैन करें';
+
+ @override
String get scrimLabel => 'स्क्रिम';
@override
@@ -18040,6 +18124,9 @@
String get saveButtonLabel => 'Spremi';
@override
+ String get scanTextButtonLabel => 'Skeniraj tekst';
+
+ @override
String get scrimLabel => 'Rubno';
@override
@@ -18515,6 +18602,9 @@
String get saveButtonLabel => 'Mentés';
@override
+ String get scanTextButtonLabel => 'Szöveg beolvasása';
+
+ @override
String get scrimLabel => 'Borítás';
@override
@@ -18990,6 +19080,9 @@
String get saveButtonLabel => 'Պահել';
@override
+ String get scanTextButtonLabel => 'Սկանավորեք տեքստը';
+
+ @override
String get scrimLabel => 'Դիմակ';
@override
@@ -19465,6 +19558,9 @@
String get saveButtonLabel => 'Simpan';
@override
+ String get scanTextButtonLabel => 'Pindai teks';
+
+ @override
String get scrimLabel => 'Scrim';
@override
@@ -19940,6 +20036,9 @@
String get saveButtonLabel => 'Vista';
@override
+ String get scanTextButtonLabel => 'Skannaðu texta';
+
+ @override
String get scrimLabel => 'Möskvi';
@override
@@ -20415,6 +20514,9 @@
String get saveButtonLabel => 'Salva';
@override
+ String get scanTextButtonLabel => 'Scansiona il testo';
+
+ @override
String get scrimLabel => 'Rete';
@override
@@ -20890,6 +20992,9 @@
String get saveButtonLabel => '保存';
@override
+ String get scanTextButtonLabel => 'テキストをスキャン';
+
+ @override
String get scrimLabel => 'スクリム';
@override
@@ -21365,6 +21470,9 @@
String get saveButtonLabel => 'შენახვა';
@override
+ String get scanTextButtonLabel => 'ტექსტის სკანირება';
+
+ @override
String get scrimLabel => 'სკრიმი';
@override
@@ -21840,6 +21948,9 @@
String get saveButtonLabel => 'Сақтау';
@override
+ String get scanTextButtonLabel => 'Мәтінді сканерлеу';
+
+ @override
String get scrimLabel => 'Кенеп';
@override
@@ -22315,6 +22426,9 @@
String get saveButtonLabel => 'រក្សាទុក';
@override
+ String get scanTextButtonLabel => 'ស្កេនអត្ថបទ';
+
+ @override
String get scrimLabel => 'ផ្ទាំងស្រអាប់';
@override
@@ -22790,6 +22904,9 @@
String get saveButtonLabel => '\u{c89}\u{cb3}\u{cbf}\u{cb8}\u{cbf}';
@override
+ String get scanTextButtonLabel => '\u{caa}\u{ca0}\u{ccd}\u{caf}\u{cb5}\u{ca8}\u{ccd}\u{ca8}\u{cc1}\u{20}\u{cb8}\u{ccd}\u{c95}\u{ccd}\u{caf}\u{cbe}\u{ca8}\u{ccd}\u{20}\u{cae}\u{cbe}\u{ca1}\u{cbf}';
+
+ @override
String get scrimLabel => '\u{cb8}\u{ccd}\u{c95}\u{ccd}\u{cb0}\u{cbf}\u{cae}\u{ccd}';
@override
@@ -23265,6 +23382,9 @@
String get saveButtonLabel => '저장';
@override
+ String get scanTextButtonLabel => '스캔 텍스트';
+
+ @override
String get scrimLabel => '스크림';
@override
@@ -23740,6 +23860,9 @@
String get saveButtonLabel => 'Сактоо';
@override
+ String get scanTextButtonLabel => 'Текстти скандоо';
+
+ @override
String get scrimLabel => 'Кенеп';
@override
@@ -24215,6 +24338,9 @@
String get saveButtonLabel => 'ບັນທຶກ';
@override
+ String get scanTextButtonLabel => 'ສະແກນຂໍ້ຄວາມ';
+
+ @override
String get scrimLabel => 'Scrim';
@override
@@ -24690,6 +24816,9 @@
String get saveButtonLabel => 'Išsaugoti';
@override
+ String get scanTextButtonLabel => 'Nuskaityti tekstą';
+
+ @override
String get scrimLabel => 'Užsklanda';
@override
@@ -25165,6 +25294,9 @@
String get saveButtonLabel => 'Saglabāt';
@override
+ String get scanTextButtonLabel => 'Skenēt tekstu';
+
+ @override
String get scrimLabel => 'Pārklājums';
@override
@@ -25640,6 +25772,9 @@
String get saveButtonLabel => 'Зачувај';
@override
+ String get scanTextButtonLabel => 'Скенирајте текст';
+
+ @override
String get scrimLabel => 'Скрим';
@override
@@ -26115,6 +26250,9 @@
String get saveButtonLabel => 'സംരക്ഷിക്കുക';
@override
+ String get scanTextButtonLabel => 'ടെക്സ്റ്റ് സ്കാൻ ചെയ്യുക';
+
+ @override
String get scrimLabel => 'സ്ക്രിം';
@override
@@ -26590,6 +26728,9 @@
String get saveButtonLabel => 'Хадгалах';
@override
+ String get scanTextButtonLabel => 'Текст сканнердах';
+
+ @override
String get scrimLabel => 'Скрим';
@override
@@ -27065,6 +27206,9 @@
String get saveButtonLabel => 'सेव्ह करा';
@override
+ String get scanTextButtonLabel => 'मजकूर स्कॅन करा';
+
+ @override
String get scrimLabel => 'स्क्रिम';
@override
@@ -27540,6 +27684,9 @@
String get saveButtonLabel => 'Simpan';
@override
+ String get scanTextButtonLabel => 'Pindai teks';
+
+ @override
String get scrimLabel => 'Scrim';
@override
@@ -28015,6 +28162,9 @@
String get saveButtonLabel => 'သိမ်းရန်';
@override
+ String get scanTextButtonLabel => 'စာသားကို စကင်ဖတ်ပါ။';
+
+ @override
String get scrimLabel => 'Scrim';
@override
@@ -28490,6 +28640,9 @@
String get saveButtonLabel => 'Lagre';
@override
+ String get scanTextButtonLabel => 'Scan tekst';
+
+ @override
String get scrimLabel => 'Vev';
@override
@@ -28965,6 +29118,9 @@
String get saveButtonLabel => 'सेभ गर्नुहोस्';
@override
+ String get scanTextButtonLabel => 'पाठ स्क्यान गर्नुहोस्';
+
+ @override
String get scrimLabel => 'स्क्रिम';
@override
@@ -29440,6 +29596,9 @@
String get saveButtonLabel => 'Opslaan';
@override
+ String get scanTextButtonLabel => 'Tekst scannen';
+
+ @override
String get scrimLabel => 'Scrim';
@override
@@ -29915,6 +30074,9 @@
String get saveButtonLabel => 'Lagre';
@override
+ String get scanTextButtonLabel => 'Skann tekst';
+
+ @override
String get scrimLabel => 'Vev';
@override
@@ -30390,6 +30552,9 @@
String get saveButtonLabel => 'ସେଭ କରନ୍ତୁ';
@override
+ String get scanTextButtonLabel => 'ପାଠ୍ୟ ସ୍କାନ୍ କରନ୍ତୁ';
+
+ @override
String get scrimLabel => 'ସ୍କ୍ରିମ';
@override
@@ -30865,6 +31030,9 @@
String get saveButtonLabel => 'ਰੱਖਿਅਤ ਕਰੋ';
@override
+ String get scanTextButtonLabel => 'ਟੈਕਸਟ ਸਕੈਨ ਕਰੋ';
+
+ @override
String get scrimLabel => 'ਸਕ੍ਰਿਮ';
@override
@@ -31340,6 +31508,9 @@
String get saveButtonLabel => 'Zapisz';
@override
+ String get scanTextButtonLabel => 'Zeskanuj tekst';
+
+ @override
String get scrimLabel => 'Siatka';
@override
@@ -31815,6 +31986,9 @@
String get saveButtonLabel => 'SAVE';
@override
+ String get scanTextButtonLabel => 'متن سکین کړئ';
+
+ @override
String get scrimLabel => 'Scrim';
@override
@@ -32290,6 +32464,9 @@
String get saveButtonLabel => 'Salvar';
@override
+ String get scanTextButtonLabel => 'Digitalizar texto';
+
+ @override
String get scrimLabel => 'Scrim';
@override
@@ -32916,6 +33093,9 @@
String get saveButtonLabel => 'Salvați';
@override
+ String get scanTextButtonLabel => 'Scanați textul';
+
+ @override
String get scrimLabel => 'Material';
@override
@@ -33391,6 +33571,9 @@
String get saveButtonLabel => 'Сохранить';
@override
+ String get scanTextButtonLabel => 'Сканировать текст';
+
+ @override
String get scrimLabel => 'Маска';
@override
@@ -33866,6 +34049,9 @@
String get saveButtonLabel => 'සුරකින්න';
@override
+ String get scanTextButtonLabel => 'පෙළ පරිලෝකනය කරන්න';
+
+ @override
String get scrimLabel => 'ස්ක්රිම්';
@override
@@ -34341,6 +34527,9 @@
String get saveButtonLabel => 'Uložiť';
@override
+ String get scanTextButtonLabel => 'Naskenujte text';
+
+ @override
String get scrimLabel => 'Scrim';
@override
@@ -34816,6 +35005,9 @@
String get saveButtonLabel => 'Shrani';
@override
+ String get scanTextButtonLabel => 'Skeniraj besedilo';
+
+ @override
String get scrimLabel => 'Scrim';
@override
@@ -35291,6 +35483,9 @@
String get saveButtonLabel => 'Ruaj';
@override
+ String get scanTextButtonLabel => 'Skanoni tekstin';
+
+ @override
String get scrimLabel => 'Kanavacë';
@override
@@ -35766,6 +35961,9 @@
String get saveButtonLabel => 'Сачувај';
@override
+ String get scanTextButtonLabel => 'Скенирајте текст';
+
+ @override
String get scrimLabel => 'Скрим';
@override
@@ -36555,6 +36753,9 @@
String get saveButtonLabel => 'Spara';
@override
+ String get scanTextButtonLabel => 'Skanna text';
+
+ @override
String get scrimLabel => 'Scrim';
@override
@@ -37030,6 +37231,9 @@
String get saveButtonLabel => 'Hifadhi';
@override
+ String get scanTextButtonLabel => 'Changanua maandishi';
+
+ @override
String get scrimLabel => 'Scrim';
@override
@@ -37505,6 +37709,9 @@
String get saveButtonLabel => 'சேமி';
@override
+ String get scanTextButtonLabel => 'உரையை ஸ்கேன் செய்யவும்';
+
+ @override
String get scrimLabel => 'ஸ்க்ரிம்';
@override
@@ -37980,6 +38187,9 @@
String get saveButtonLabel => 'సేవ్ చేయండి';
@override
+ String get scanTextButtonLabel => 'వచనాన్ని స్కాన్ చేయండి';
+
+ @override
String get scrimLabel => 'స్క్రిమ్';
@override
@@ -38455,6 +38665,9 @@
String get saveButtonLabel => 'บันทึก';
@override
+ String get scanTextButtonLabel => 'สแกนข้อความ';
+
+ @override
String get scrimLabel => 'Scrim';
@override
@@ -38930,6 +39143,9 @@
String get saveButtonLabel => 'I-save';
@override
+ String get scanTextButtonLabel => 'I-scan ang text';
+
+ @override
String get scrimLabel => 'Scrim';
@override
@@ -39405,6 +39621,9 @@
String get saveButtonLabel => 'Kaydet';
@override
+ String get scanTextButtonLabel => 'Metni tara';
+
+ @override
String get scrimLabel => 'opaklık katmanı';
@override
@@ -39880,6 +40099,9 @@
String get saveButtonLabel => 'Зберегти';
@override
+ String get scanTextButtonLabel => 'Сканувати текст';
+
+ @override
String get scrimLabel => 'Маскувальний фон';
@override
@@ -40355,6 +40577,9 @@
String get saveButtonLabel => 'محفوظ کریں';
@override
+ String get scanTextButtonLabel => 'متن کو اسکین کریں';
+
+ @override
String get scrimLabel => 'اسکریم';
@override
@@ -40830,6 +41055,9 @@
String get saveButtonLabel => 'Saqlash';
@override
+ String get scanTextButtonLabel => 'Matnni skanerlash';
+
+ @override
String get scrimLabel => 'Kanop';
@override
@@ -41305,6 +41533,9 @@
String get saveButtonLabel => 'Lưu';
@override
+ String get scanTextButtonLabel => 'Quét văn bản';
+
+ @override
String get scrimLabel => 'Scrim';
@override
@@ -41780,6 +42011,9 @@
String get saveButtonLabel => '保存';
@override
+ String get scanTextButtonLabel => '扫描文本';
+
+ @override
String get scrimLabel => '纱罩';
@override
@@ -42748,6 +42982,9 @@
String get saveButtonLabel => 'Londoloza';
@override
+ String get scanTextButtonLabel => 'Skena umbhalo';
+
+ @override
String get scrimLabel => 'I-Scrim';
@override
diff --git a/packages/flutter_localizations/lib/src/l10n/material_af.arb b/packages/flutter_localizations/lib/src/l10n/material_af.arb
index 9305eaf..c593ac8 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_af.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_af.arb
@@ -25,6 +25,7 @@
"continueButtonLabel": "Gaan voort",
"copyButtonLabel": "Kopieer",
"cutButtonLabel": "Knip",
+ "scanTextButtonLabel": "Skena umbhalo",
"okButtonLabel": "OK",
"pasteButtonLabel": "Plak",
"selectAllButtonLabel": "Kies alles",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_am.arb b/packages/flutter_localizations/lib/src/l10n/material_am.arb
index 9252e27..3538c87 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_am.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_am.arb
@@ -25,6 +25,7 @@
"continueButtonLabel": "ቀጥል",
"copyButtonLabel": "ቅዳ",
"cutButtonLabel": "ቁረጥ",
+ "scanTextButtonLabel": "ጽሑፍ ይቃኙ",
"okButtonLabel": "እሺ",
"pasteButtonLabel": "ለጥፍ",
"selectAllButtonLabel": "ሁሉንም ምረጥ",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_ar.arb b/packages/flutter_localizations/lib/src/l10n/material_ar.arb
index 09e0deb..73f9d2b 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_ar.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_ar.arb
@@ -35,6 +35,7 @@
"continueButtonLabel": "المتابعة",
"copyButtonLabel": "نسخ",
"cutButtonLabel": "قص",
+ "scanTextButtonLabel": "مسح النص",
"okButtonLabel": "حسنًا",
"pasteButtonLabel": "لصق",
"selectAllButtonLabel": "اختيار الكل",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_as.arb b/packages/flutter_localizations/lib/src/l10n/material_as.arb
index 947cb77..f358a74 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_as.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_as.arb
@@ -25,6 +25,7 @@
"continueButtonLabel": "অব্যাহত ৰাখক",
"copyButtonLabel": "প্ৰতিলিপি কৰক",
"cutButtonLabel": "কাট কৰক",
+ "scanTextButtonLabel": "স্কেন টেক্সট",
"okButtonLabel": "ঠিক আছে",
"pasteButtonLabel": "পে'ষ্ট কৰক",
"selectAllButtonLabel": "সকলো বাছনি কৰক",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_az.arb b/packages/flutter_localizations/lib/src/l10n/material_az.arb
index ecda4f6..ea0736f 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_az.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_az.arb
@@ -25,6 +25,7 @@
"continueButtonLabel": "Davam edin",
"copyButtonLabel": "Kopyalayın",
"cutButtonLabel": "Kəsin",
+ "scanTextButtonLabel": "Mətni skan edin",
"okButtonLabel": "OK",
"pasteButtonLabel": "Yerləşdirin",
"selectAllButtonLabel": "Hamısını seçin",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_be.arb b/packages/flutter_localizations/lib/src/l10n/material_be.arb
index d370cfa..d58cb14 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_be.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_be.arb
@@ -31,6 +31,7 @@
"continueButtonLabel": "Працягнуць",
"copyButtonLabel": "Капіраваць",
"cutButtonLabel": "Выразаць",
+ "scanTextButtonLabel": "Сканаваць тэкст",
"okButtonLabel": "ОК",
"pasteButtonLabel": "Уставіць",
"selectAllButtonLabel": "Выбраць усе",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_bg.arb b/packages/flutter_localizations/lib/src/l10n/material_bg.arb
index bc18ea7..fb6074c 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_bg.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_bg.arb
@@ -25,6 +25,7 @@
"continueButtonLabel": "Напред",
"copyButtonLabel": "Копиране",
"cutButtonLabel": "Изрязване",
+ "scanTextButtonLabel": "Сканиране на текст",
"okButtonLabel": "OK",
"pasteButtonLabel": "Поставяне",
"selectAllButtonLabel": "Избиране на всички",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_bn.arb b/packages/flutter_localizations/lib/src/l10n/material_bn.arb
index cb6809b..03587bc 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_bn.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_bn.arb
@@ -25,6 +25,7 @@
"continueButtonLabel": "চালিয়ে যান",
"copyButtonLabel": "কপি করুন",
"cutButtonLabel": "কাট করুন",
+ "scanTextButtonLabel": "পাঠ্য স্ক্যান করুন",
"okButtonLabel": "ঠিক আছে",
"pasteButtonLabel": "পেস্ট করুন",
"selectAllButtonLabel": "সব বেছে নিন",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_bs.arb b/packages/flutter_localizations/lib/src/l10n/material_bs.arb
index 8915688..bbe68a1 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_bs.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_bs.arb
@@ -28,6 +28,7 @@
"continueButtonLabel": "Nastavi",
"copyButtonLabel": "Kopiraj",
"cutButtonLabel": "Izreži",
+ "scanTextButtonLabel": "Skeniraj tekst",
"okButtonLabel": "Uredu",
"pasteButtonLabel": "Zalijepi",
"selectAllButtonLabel": "Odaberi sve",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_ca.arb b/packages/flutter_localizations/lib/src/l10n/material_ca.arb
index 031a078..aecdb08 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_ca.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_ca.arb
@@ -25,6 +25,7 @@
"continueButtonLabel": "Continua",
"copyButtonLabel": "Copia",
"cutButtonLabel": "Retalla",
+ "scanTextButtonLabel": "Escaneja el text",
"okButtonLabel": "D'ACORD",
"pasteButtonLabel": "Enganxa",
"selectAllButtonLabel": "Selecciona-ho tot",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_cs.arb b/packages/flutter_localizations/lib/src/l10n/material_cs.arb
index 4dcd062..1e17c2e 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_cs.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_cs.arb
@@ -31,6 +31,7 @@
"continueButtonLabel": "Pokračovat",
"copyButtonLabel": "Kopírovat",
"cutButtonLabel": "Vyjmout",
+ "scanTextButtonLabel": "Naskenujte text",
"okButtonLabel": "OK",
"pasteButtonLabel": "Vložit",
"selectAllButtonLabel": "Vybrat vše",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_cy.arb b/packages/flutter_localizations/lib/src/l10n/material_cy.arb
index 35831c8..1cf88af 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_cy.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_cy.arb
@@ -150,5 +150,6 @@
"expansionTileExpandedTapHint": "Collapse",
"expansionTileCollapsedTapHint": "Expand for more details",
"expandedHint": "Collapsed",
- "collapsedHint": "Expanded"
+ "collapsedHint": "Expanded",
+ "scanTextButtonLabel": "Scan text"
}
diff --git a/packages/flutter_localizations/lib/src/l10n/material_da.arb b/packages/flutter_localizations/lib/src/l10n/material_da.arb
index 98d147e..52c309e 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_da.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_da.arb
@@ -25,6 +25,7 @@
"continueButtonLabel": "Fortsæt",
"copyButtonLabel": "Kopiér",
"cutButtonLabel": "Klip",
+ "scanTextButtonLabel": "Scan tekst",
"okButtonLabel": "OK",
"pasteButtonLabel": "Indsæt",
"selectAllButtonLabel": "Markér alt",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_de.arb b/packages/flutter_localizations/lib/src/l10n/material_de.arb
index f72cfe3..9a5fbef 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_de.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_de.arb
@@ -26,6 +26,7 @@
"continueButtonLabel": "Weiter",
"copyButtonLabel": "Kopieren",
"cutButtonLabel": "Ausschneiden",
+ "scanTextButtonLabel": "Text scannen",
"okButtonLabel": "OK",
"pasteButtonLabel": "Einsetzen",
"selectAllButtonLabel": "Alle auswählen",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_el.arb b/packages/flutter_localizations/lib/src/l10n/material_el.arb
index c072774..e9f3408 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_el.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_el.arb
@@ -25,6 +25,7 @@
"continueButtonLabel": "Συνέχεια",
"copyButtonLabel": "Αντιγραφή",
"cutButtonLabel": "Αποκοπή",
+ "scanTextButtonLabel": "Σάρωση κειμένου",
"okButtonLabel": "ΟΚ",
"pasteButtonLabel": "Επικόλληση",
"selectAllButtonLabel": "Επιλογή όλων",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_en.arb b/packages/flutter_localizations/lib/src/l10n/material_en.arb
index dc2e11e..dd9746d 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_en.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_en.arb
@@ -192,6 +192,11 @@
"description": "The label for cut buttons and menu items."
},
+ "scanTextButtonLabel": "Scan text",
+ "@scanTextButtonLabel": {
+ "description": "The label for scan text buttons and menu items for starting the insertion of text via OCR."
+ },
+
"okButtonLabel": "OK",
"@okButtonLabel": {
"description": "The label for OK buttons and menu items."
diff --git a/packages/flutter_localizations/lib/src/l10n/material_es.arb b/packages/flutter_localizations/lib/src/l10n/material_es.arb
index 4ceef3a..59eed0c 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_es.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_es.arb
@@ -26,6 +26,7 @@
"continueButtonLabel": "Continuar",
"copyButtonLabel": "Copiar",
"cutButtonLabel": "Cortar",
+ "scanTextButtonLabel": "Escanear texto",
"okButtonLabel": "ACEPTAR",
"pasteButtonLabel": "Pegar",
"selectAllButtonLabel": "Seleccionar todo",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_et.arb b/packages/flutter_localizations/lib/src/l10n/material_et.arb
index 90f8c50..97fb40a 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_et.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_et.arb
@@ -25,6 +25,7 @@
"continueButtonLabel": "Jätka",
"copyButtonLabel": "Kopeeri",
"cutButtonLabel": "Lõika",
+ "scanTextButtonLabel": "Skanni teksti",
"okButtonLabel": "OK",
"pasteButtonLabel": "Kleebi",
"selectAllButtonLabel": "Vali kõik",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_eu.arb b/packages/flutter_localizations/lib/src/l10n/material_eu.arb
index 3d0b043..8e29921 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_eu.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_eu.arb
@@ -25,6 +25,7 @@
"continueButtonLabel": "Egin aurrera",
"copyButtonLabel": "Kopiatu",
"cutButtonLabel": "Ebaki",
+ "scanTextButtonLabel": "Eskaneatu testua",
"okButtonLabel": "Ados",
"pasteButtonLabel": "Itsatsi",
"selectAllButtonLabel": "Hautatu guztiak",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_fa.arb b/packages/flutter_localizations/lib/src/l10n/material_fa.arb
index 7dc1bcd..20c7fbc 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_fa.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_fa.arb
@@ -25,6 +25,7 @@
"continueButtonLabel": "ادامه",
"copyButtonLabel": "کپی",
"cutButtonLabel": "برش",
+ "scanTextButtonLabel": "اسکن متن",
"okButtonLabel": "تأیید",
"pasteButtonLabel": "جایگذاری",
"selectAllButtonLabel": "انتخاب همه",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_fi.arb b/packages/flutter_localizations/lib/src/l10n/material_fi.arb
index ba4ce53..8db1a1a 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_fi.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_fi.arb
@@ -25,6 +25,7 @@
"continueButtonLabel": "Jatka",
"copyButtonLabel": "Kopioi",
"cutButtonLabel": "Leikkaa",
+ "scanTextButtonLabel": "Skannaa tekstiä",
"okButtonLabel": "OK",
"pasteButtonLabel": "Liitä",
"selectAllButtonLabel": "Valitse kaikki",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_fil.arb b/packages/flutter_localizations/lib/src/l10n/material_fil.arb
index c154184..fbf38a1 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_fil.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_fil.arb
@@ -25,6 +25,7 @@
"continueButtonLabel": "Magpatuloy",
"copyButtonLabel": "Kopyahin",
"cutButtonLabel": "I-cut",
+ "scanTextButtonLabel": "I-scan ang text",
"okButtonLabel": "OK",
"pasteButtonLabel": "I-paste",
"selectAllButtonLabel": "Piliin lahat",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_fr.arb b/packages/flutter_localizations/lib/src/l10n/material_fr.arb
index 39f5122..accbb33 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_fr.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_fr.arb
@@ -26,6 +26,7 @@
"continueButtonLabel": "Continuer",
"copyButtonLabel": "Copier",
"cutButtonLabel": "Couper",
+ "scanTextButtonLabel": "Numériser du texte",
"okButtonLabel": "OK",
"pasteButtonLabel": "Coller",
"selectAllButtonLabel": "Tout sélectionner",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_gl.arb b/packages/flutter_localizations/lib/src/l10n/material_gl.arb
index 0e8a200..2557795 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_gl.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_gl.arb
@@ -26,6 +26,7 @@
"continueButtonLabel": "Continuar",
"copyButtonLabel": "Copiar",
"cutButtonLabel": "Cortar",
+ "scanTextButtonLabel": "Escanear texto",
"okButtonLabel": "Aceptar",
"pasteButtonLabel": "Pegar",
"selectAllButtonLabel": "Seleccionar todo",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_gsw.arb b/packages/flutter_localizations/lib/src/l10n/material_gsw.arb
index f8a66c8..1d803e7 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_gsw.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_gsw.arb
@@ -30,6 +30,7 @@
"continueButtonLabel": "Weiter",
"copyButtonLabel": "Kopieren",
"cutButtonLabel": "Ausschneiden",
+ "scanTextButtonLabel": "Text scannen",
"okButtonLabel": "OK",
"pasteButtonLabel": "Einsetzen",
"selectAllButtonLabel": "Alle auswählen",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_gu.arb b/packages/flutter_localizations/lib/src/l10n/material_gu.arb
index 053afe5..371690c 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_gu.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_gu.arb
@@ -25,6 +25,7 @@
"continueButtonLabel": "ચાલુ રાખો",
"copyButtonLabel": "કૉપિ કરો",
"cutButtonLabel": "કાપો",
+ "scanTextButtonLabel": "ટેક્સ્ટ સ્કેન કરો",
"okButtonLabel": "ઓકે",
"pasteButtonLabel": "પેસ્ટ કરો",
"selectAllButtonLabel": "બધા પસંદ કરો",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_he.arb b/packages/flutter_localizations/lib/src/l10n/material_he.arb
index 73991d6..c1f33f5 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_he.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_he.arb
@@ -31,6 +31,7 @@
"continueButtonLabel": "המשך",
"copyButtonLabel": "העתקה",
"cutButtonLabel": "גזירה",
+ "scanTextButtonLabel": "סרוק טקסט",
"okButtonLabel": "אישור",
"pasteButtonLabel": "הדבקה",
"selectAllButtonLabel": "בחירת הכול",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_hi.arb b/packages/flutter_localizations/lib/src/l10n/material_hi.arb
index 4ccdf90..78fe9a1 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_hi.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_hi.arb
@@ -25,6 +25,7 @@
"continueButtonLabel": "जारी रखें",
"copyButtonLabel": "कॉपी करें",
"cutButtonLabel": "काटें",
+ "scanTextButtonLabel": "पाठ स्कैन करें",
"okButtonLabel": "ठीक है",
"pasteButtonLabel": "चिपकाएं",
"selectAllButtonLabel": "सभी को चुनें",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_hr.arb b/packages/flutter_localizations/lib/src/l10n/material_hr.arb
index 1a19917..7535eb9 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_hr.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_hr.arb
@@ -28,6 +28,7 @@
"continueButtonLabel": "Nastavi",
"copyButtonLabel": "Kopiraj",
"cutButtonLabel": "Izreži",
+ "scanTextButtonLabel": "Skeniraj tekst",
"okButtonLabel": "U REDU",
"pasteButtonLabel": "Zalijepi",
"selectAllButtonLabel": "Odaberi sve",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_hu.arb b/packages/flutter_localizations/lib/src/l10n/material_hu.arb
index 654be05..88c57ae 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_hu.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_hu.arb
@@ -25,6 +25,7 @@
"continueButtonLabel": "Folytatás",
"copyButtonLabel": "Másolás",
"cutButtonLabel": "Kivágás",
+ "scanTextButtonLabel": "Szöveg beolvasása",
"okButtonLabel": "OK",
"pasteButtonLabel": "Beillesztés",
"selectAllButtonLabel": "Összes kijelölése",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_hy.arb b/packages/flutter_localizations/lib/src/l10n/material_hy.arb
index 4e1d29c..02d1ab8 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_hy.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_hy.arb
@@ -30,6 +30,7 @@
"continueButtonLabel": "Շարունակել",
"copyButtonLabel": "Պատճենել",
"cutButtonLabel": "Կտրել",
+ "scanTextButtonLabel": "Սկանավորեք տեքստը",
"okButtonLabel": "Եղավ",
"pasteButtonLabel": "Տեղադրել",
"selectAllButtonLabel": "Նշել բոլորը",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_id.arb b/packages/flutter_localizations/lib/src/l10n/material_id.arb
index e48f988..131bfac 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_id.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_id.arb
@@ -25,6 +25,7 @@
"continueButtonLabel": "Lanjutkan",
"copyButtonLabel": "Salin",
"cutButtonLabel": "Potong",
+ "scanTextButtonLabel": "Pindai teks",
"okButtonLabel": "OKE",
"pasteButtonLabel": "Tempel",
"selectAllButtonLabel": "Pilih semua",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_is.arb b/packages/flutter_localizations/lib/src/l10n/material_is.arb
index 2dfd4ed..30078d7 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_is.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_is.arb
@@ -25,6 +25,7 @@
"continueButtonLabel": "Áfram",
"copyButtonLabel": "Afrita",
"cutButtonLabel": "Klippa",
+ "scanTextButtonLabel": "Skannaðu texta",
"okButtonLabel": "Í lagi",
"pasteButtonLabel": "Líma",
"selectAllButtonLabel": "Velja allt",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_it.arb b/packages/flutter_localizations/lib/src/l10n/material_it.arb
index 9f7f4a8..1f35104 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_it.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_it.arb
@@ -25,6 +25,7 @@
"continueButtonLabel": "Continua",
"copyButtonLabel": "Copia",
"cutButtonLabel": "Taglia",
+ "scanTextButtonLabel": "Scansiona il testo",
"okButtonLabel": "OK",
"pasteButtonLabel": "Incolla",
"selectAllButtonLabel": "Seleziona tutto",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_ja.arb b/packages/flutter_localizations/lib/src/l10n/material_ja.arb
index 59f145f..58e3c81 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_ja.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_ja.arb
@@ -25,6 +25,7 @@
"continueButtonLabel": "続行",
"copyButtonLabel": "コピー",
"cutButtonLabel": "切り取り",
+ "scanTextButtonLabel": "テキストをスキャン",
"okButtonLabel": "OK",
"pasteButtonLabel": "貼り付け",
"selectAllButtonLabel": "すべて選択",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_ka.arb b/packages/flutter_localizations/lib/src/l10n/material_ka.arb
index 36ff3fe..b221c94 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_ka.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_ka.arb
@@ -25,6 +25,7 @@
"continueButtonLabel": "გაგრძელება",
"copyButtonLabel": "კოპირება",
"cutButtonLabel": "ამოჭრა",
+ "scanTextButtonLabel": "ტექსტის სკანირება",
"okButtonLabel": "კარგი",
"pasteButtonLabel": "ჩასმა",
"selectAllButtonLabel": "ყველას არჩევა",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_kk.arb b/packages/flutter_localizations/lib/src/l10n/material_kk.arb
index b35d598..a318f00 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_kk.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_kk.arb
@@ -27,6 +27,7 @@
"continueButtonLabel": "Жалғастыру",
"copyButtonLabel": "Көшіру",
"cutButtonLabel": "Қию",
+ "scanTextButtonLabel": "Мәтінді сканерлеу",
"okButtonLabel": "Иә",
"pasteButtonLabel": "Қою",
"selectAllButtonLabel": "Барлығын таңдау",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_km.arb b/packages/flutter_localizations/lib/src/l10n/material_km.arb
index 7d61ff7..9c2a624 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_km.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_km.arb
@@ -25,6 +25,7 @@
"continueButtonLabel": "បន្ត",
"copyButtonLabel": "ចម្លង",
"cutButtonLabel": "កាត់",
+ "scanTextButtonLabel": "ស្កេនអត្ថបទ",
"okButtonLabel": "យល់ព្រម",
"pasteButtonLabel": "ដាក់ចូល",
"selectAllButtonLabel": "ជ្រើសរើសទាំងអស់",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_kn.arb b/packages/flutter_localizations/lib/src/l10n/material_kn.arb
index 7beddc5..624941d 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_kn.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_kn.arb
@@ -25,6 +25,7 @@
"continueButtonLabel": "\u0cae\u0cc1\u0c82\u0ca6\u0cc1\u0cb5\u0cb0\u0cbf\u0cb8\u0cbf",
"copyButtonLabel": "\u0ca8\u0c95\u0cb2\u0cbf\u0cb8\u0cbf",
"cutButtonLabel": "\u0c95\u0ca4\u0ccd\u0ca4\u0cb0\u0cbf\u0cb8\u0cbf",
+ "scanTextButtonLabel": "\u0caa\u0ca0\u0ccd\u0caf\u0cb5\u0ca8\u0ccd\u0ca8\u0cc1\u0020\u0cb8\u0ccd\u0c95\u0ccd\u0caf\u0cbe\u0ca8\u0ccd\u0020\u0cae\u0cbe\u0ca1\u0cbf",
"okButtonLabel": "\u0cb8\u0cb0\u0cbf",
"pasteButtonLabel": "\u0c85\u0c82\u0c9f\u0cbf\u0cb8\u0cbf",
"selectAllButtonLabel": "\u0c8e\u0cb2\u0ccd\u0cb2\u0cb5\u0ca8\u0ccd\u0ca8\u0cc2\u0020\u0c86\u0caf\u0ccd\u0c95\u0cc6\u0020\u0cae\u0cbe\u0ca1\u0cbf",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_ko.arb b/packages/flutter_localizations/lib/src/l10n/material_ko.arb
index b0d7fc8..4b2eeee 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_ko.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_ko.arb
@@ -25,6 +25,7 @@
"continueButtonLabel": "계속",
"copyButtonLabel": "복사",
"cutButtonLabel": "잘라냄",
+ "scanTextButtonLabel": "스캔 텍스트",
"okButtonLabel": "확인",
"pasteButtonLabel": "붙여넣기",
"selectAllButtonLabel": "전체 선택",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_ky.arb b/packages/flutter_localizations/lib/src/l10n/material_ky.arb
index e751ea3..568e08e 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_ky.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_ky.arb
@@ -25,6 +25,7 @@
"continueButtonLabel": "Улантуу",
"copyButtonLabel": "Көчүрүү",
"cutButtonLabel": "Кесүү",
+ "scanTextButtonLabel": "Текстти скандоо",
"okButtonLabel": "Макул",
"pasteButtonLabel": "Чаптоо",
"selectAllButtonLabel": "Баарын тандоо",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_lo.arb b/packages/flutter_localizations/lib/src/l10n/material_lo.arb
index c28b7be..2b02046 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_lo.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_lo.arb
@@ -25,6 +25,7 @@
"continueButtonLabel": "ສືບຕໍ່",
"copyButtonLabel": "ສຳເນົາ",
"cutButtonLabel": "ຕັດ",
+ "scanTextButtonLabel": "ສະແກນຂໍ້ຄວາມ",
"okButtonLabel": "ຕົກລົງ",
"pasteButtonLabel": "ວາງ",
"selectAllButtonLabel": "ເລືອກທັງໝົດ",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_lt.arb b/packages/flutter_localizations/lib/src/l10n/material_lt.arb
index 82bf6e2..62d77cb 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_lt.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_lt.arb
@@ -31,6 +31,7 @@
"continueButtonLabel": "Tęsti",
"copyButtonLabel": "Kopijuoti",
"cutButtonLabel": "Iškirpti",
+ "scanTextButtonLabel": "Nuskaityti tekstą",
"okButtonLabel": "GERAI",
"pasteButtonLabel": "Įklijuoti",
"selectAllButtonLabel": "Pasirinkti viską",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_lv.arb b/packages/flutter_localizations/lib/src/l10n/material_lv.arb
index 62bdf7e..3c84e58 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_lv.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_lv.arb
@@ -26,6 +26,7 @@
"continueButtonLabel": "Turpināt",
"copyButtonLabel": "Kopēt",
"cutButtonLabel": "Izgriezt",
+ "scanTextButtonLabel": "Skenēt tekstu",
"okButtonLabel": "LABI",
"pasteButtonLabel": "Ielīmēt",
"selectAllButtonLabel": "Atlasīt visu",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_mk.arb b/packages/flutter_localizations/lib/src/l10n/material_mk.arb
index 8f479b8..99586cb 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_mk.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_mk.arb
@@ -25,6 +25,7 @@
"continueButtonLabel": "Продолжи",
"copyButtonLabel": "Копирај",
"cutButtonLabel": "Исечи",
+ "scanTextButtonLabel": "Скенирајте текст",
"okButtonLabel": "Во ред",
"pasteButtonLabel": "Залепи",
"selectAllButtonLabel": "Избери ги сите",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_ml.arb b/packages/flutter_localizations/lib/src/l10n/material_ml.arb
index bda009d..2889635 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_ml.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_ml.arb
@@ -25,6 +25,7 @@
"continueButtonLabel": "തുടരുക",
"copyButtonLabel": "പകർത്തുക",
"cutButtonLabel": "മുറിക്കുക",
+ "scanTextButtonLabel": "ടെക്സ്റ്റ് സ്കാൻ ചെയ്യുക",
"okButtonLabel": "ശരി",
"pasteButtonLabel": "ഒട്ടിക്കുക",
"selectAllButtonLabel": "എല്ലാം തിരഞ്ഞെടുക്കുക",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_mn.arb b/packages/flutter_localizations/lib/src/l10n/material_mn.arb
index 9d2cd46..a960b7b 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_mn.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_mn.arb
@@ -26,6 +26,7 @@
"continueButtonLabel": "Үргэлжлүүлэх",
"copyButtonLabel": "Хуулах",
"cutButtonLabel": "Таслах",
+ "scanTextButtonLabel": "Текст сканнердах",
"okButtonLabel": "OK",
"pasteButtonLabel": "Буулгах",
"selectAllButtonLabel": "Бүгдийг сонгох",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_mr.arb b/packages/flutter_localizations/lib/src/l10n/material_mr.arb
index 35b68b5..ccc1ab9 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_mr.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_mr.arb
@@ -26,6 +26,7 @@
"continueButtonLabel": "पुढे सुरू ठेवा",
"copyButtonLabel": "कॉपी करा",
"cutButtonLabel": "कट करा",
+ "scanTextButtonLabel": "मजकूर स्कॅन करा",
"okButtonLabel": "ओके",
"pasteButtonLabel": "पेस्ट करा",
"selectAllButtonLabel": "सर्व निवडा",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_ms.arb b/packages/flutter_localizations/lib/src/l10n/material_ms.arb
index fed2636..2efd94a 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_ms.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_ms.arb
@@ -26,6 +26,7 @@
"continueButtonLabel": "Teruskan",
"copyButtonLabel": "Salin",
"cutButtonLabel": "Potong",
+ "scanTextButtonLabel": "Pindai teks",
"okButtonLabel": "OK",
"pasteButtonLabel": "Tampal",
"selectAllButtonLabel": "Pilih semua",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_my.arb b/packages/flutter_localizations/lib/src/l10n/material_my.arb
index b29091e..06cde12 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_my.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_my.arb
@@ -25,6 +25,7 @@
"continueButtonLabel": "ရှေ့ဆက်ရန်",
"copyButtonLabel": "မိတ္တူကူးရန်",
"cutButtonLabel": "ဖြတ်ယူရန်",
+ "scanTextButtonLabel": "စာသားကို စကင်ဖတ်ပါ။",
"okButtonLabel": "OK",
"pasteButtonLabel": "ကူးထည့်ရန်",
"selectAllButtonLabel": "အားလုံး ရွေးရန်",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_nb.arb b/packages/flutter_localizations/lib/src/l10n/material_nb.arb
index f8e53f4..0a48105 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_nb.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_nb.arb
@@ -28,6 +28,7 @@
"continueButtonLabel": "Fortsett",
"copyButtonLabel": "Kopiér",
"cutButtonLabel": "Klipp ut",
+ "scanTextButtonLabel": "Scan tekst",
"okButtonLabel": "OK",
"pasteButtonLabel": "Lim inn",
"selectAllButtonLabel": "Velg alle",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_ne.arb b/packages/flutter_localizations/lib/src/l10n/material_ne.arb
index 55c65de..7c53636 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_ne.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_ne.arb
@@ -25,6 +25,7 @@
"continueButtonLabel": "जारी राख्नुहोस्",
"copyButtonLabel": "प्रतिलिपि गर्नुहोस्",
"cutButtonLabel": "काट्नुहोस्",
+ "scanTextButtonLabel": "पाठ स्क्यान गर्नुहोस्",
"okButtonLabel": "ठिक छ",
"pasteButtonLabel": "टाँस्नुहोस्",
"selectAllButtonLabel": "सबै बटनहरू चयन गर्नुहोस्",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_nl.arb b/packages/flutter_localizations/lib/src/l10n/material_nl.arb
index 090aa05..16d0bce 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_nl.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_nl.arb
@@ -25,6 +25,7 @@
"continueButtonLabel": "Doorgaan",
"copyButtonLabel": "Kopiëren",
"cutButtonLabel": "Knippen",
+ "scanTextButtonLabel": "Tekst scannen",
"okButtonLabel": "OK",
"pasteButtonLabel": "Plakken",
"selectAllButtonLabel": "Alles selecteren",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_no.arb b/packages/flutter_localizations/lib/src/l10n/material_no.arb
index f8e53f4..a311a70 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_no.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_no.arb
@@ -28,6 +28,7 @@
"continueButtonLabel": "Fortsett",
"copyButtonLabel": "Kopiér",
"cutButtonLabel": "Klipp ut",
+ "scanTextButtonLabel": "Skann tekst",
"okButtonLabel": "OK",
"pasteButtonLabel": "Lim inn",
"selectAllButtonLabel": "Velg alle",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_or.arb b/packages/flutter_localizations/lib/src/l10n/material_or.arb
index 834be30..299d57c 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_or.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_or.arb
@@ -25,6 +25,7 @@
"continueButtonLabel": "ଜାରି ରଖନ୍ତୁ",
"copyButtonLabel": "କପି କରନ୍ତୁ",
"cutButtonLabel": "କଟ୍ କରନ୍ତୁ",
+ "scanTextButtonLabel": "ପାଠ୍ୟ ସ୍କାନ୍ କରନ୍ତୁ",
"okButtonLabel": "ଠିକ୍ ଅଛି",
"pasteButtonLabel": "ପେଷ୍ଟ କରନ୍ତୁ",
"selectAllButtonLabel": "ସବୁ ଚୟନ କରନ୍ତୁ",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_pa.arb b/packages/flutter_localizations/lib/src/l10n/material_pa.arb
index c0d9ba7..d48c461 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_pa.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_pa.arb
@@ -25,6 +25,7 @@
"continueButtonLabel": "ਜਾਰੀ ਰੱਖੋ",
"copyButtonLabel": "ਕਾਪੀ ਕਰੋ",
"cutButtonLabel": "ਕੱਟ ਕਰੋ",
+ "scanTextButtonLabel": "ਟੈਕਸਟ ਸਕੈਨ ਕਰੋ",
"okButtonLabel": "ਠੀਕ ਹੈ",
"pasteButtonLabel": "ਪੇਸਟ ਕਰੋ",
"selectAllButtonLabel": "ਸਭ ਚੁਣੋ",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_pl.arb b/packages/flutter_localizations/lib/src/l10n/material_pl.arb
index 3385571..47695b1 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_pl.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_pl.arb
@@ -31,6 +31,7 @@
"continueButtonLabel": "Dalej",
"copyButtonLabel": "Kopiuj",
"cutButtonLabel": "Wytnij",
+ "scanTextButtonLabel": "Zeskanuj tekst",
"okButtonLabel": "OK",
"pasteButtonLabel": "Wklej",
"selectAllButtonLabel": "Zaznacz wszystko",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_ps.arb b/packages/flutter_localizations/lib/src/l10n/material_ps.arb
index 524bb28..042b805 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_ps.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_ps.arb
@@ -28,6 +28,7 @@
"continueButtonLabel": "منځپانګې",
"copyButtonLabel": "کاپی",
"cutButtonLabel": "کم کړئ",
+ "scanTextButtonLabel": "متن سکین کړئ",
"okButtonLabel": "سمه ده",
"pasteButtonLabel": "پیټ کړئ",
"selectAllButtonLabel": "غوره کړئ",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_pt.arb b/packages/flutter_localizations/lib/src/l10n/material_pt.arb
index e34cb8d..c671af7 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_pt.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_pt.arb
@@ -29,6 +29,7 @@
"continueButtonLabel": "Continuar",
"copyButtonLabel": "Copiar",
"cutButtonLabel": "Cortar",
+ "scanTextButtonLabel": "Digitalizar texto",
"okButtonLabel": "OK",
"pasteButtonLabel": "Colar",
"selectAllButtonLabel": "Selecionar tudo",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_ro.arb b/packages/flutter_localizations/lib/src/l10n/material_ro.arb
index 2c909c4..fcd7130 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_ro.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_ro.arb
@@ -29,6 +29,7 @@
"continueButtonLabel": "Continuați",
"copyButtonLabel": "Copiați",
"cutButtonLabel": "Decupați",
+ "scanTextButtonLabel": "Scanați textul",
"okButtonLabel": "OK",
"pasteButtonLabel": "Inserați",
"selectAllButtonLabel": "Selectați tot",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_ru.arb b/packages/flutter_localizations/lib/src/l10n/material_ru.arb
index 3027f58..9b81a9c 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_ru.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_ru.arb
@@ -32,6 +32,7 @@
"continueButtonLabel": "Продолжить",
"copyButtonLabel": "Копировать",
"cutButtonLabel": "Вырезать",
+ "scanTextButtonLabel": "Сканировать текст",
"okButtonLabel": "ОК",
"pasteButtonLabel": "Вставить",
"selectAllButtonLabel": "Выбрать все",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_si.arb b/packages/flutter_localizations/lib/src/l10n/material_si.arb
index f4acf36..4ac3ecf 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_si.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_si.arb
@@ -25,6 +25,7 @@
"continueButtonLabel": "ඉදිරියට යන්න",
"copyButtonLabel": "පිටපත් කරන්න",
"cutButtonLabel": "කපන්න",
+ "scanTextButtonLabel": "පෙළ පරිලෝකනය කරන්න",
"okButtonLabel": "හරි",
"pasteButtonLabel": "අලවන්න",
"selectAllButtonLabel": "සියල්ල තෝරන්න",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_sk.arb b/packages/flutter_localizations/lib/src/l10n/material_sk.arb
index deb8c5e..a85cfaf 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_sk.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_sk.arb
@@ -31,6 +31,7 @@
"continueButtonLabel": "Pokračovať",
"copyButtonLabel": "Kopírovať",
"cutButtonLabel": "Vystrihnúť",
+ "scanTextButtonLabel": "Naskenujte text",
"okButtonLabel": "OK",
"pasteButtonLabel": "Prilepiť",
"selectAllButtonLabel": "Vybrať všetko",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_sl.arb b/packages/flutter_localizations/lib/src/l10n/material_sl.arb
index dd6941d..7fe2795 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_sl.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_sl.arb
@@ -31,6 +31,7 @@
"continueButtonLabel": "Naprej",
"copyButtonLabel": "Kopiraj",
"cutButtonLabel": "Izreži",
+ "scanTextButtonLabel": "Skeniraj besedilo",
"okButtonLabel": "V REDU",
"pasteButtonLabel": "Prilepi",
"selectAllButtonLabel": "Izberi vse",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_sq.arb b/packages/flutter_localizations/lib/src/l10n/material_sq.arb
index 123b5e4..9db947b 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_sq.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_sq.arb
@@ -25,6 +25,7 @@
"continueButtonLabel": "Vazhdo",
"copyButtonLabel": "Kopjo",
"cutButtonLabel": "Prit",
+ "scanTextButtonLabel": "Skanoni tekstin",
"okButtonLabel": "Në rregull",
"pasteButtonLabel": "Ngjit",
"selectAllButtonLabel": "Zgjidh të gjitha",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_sr.arb b/packages/flutter_localizations/lib/src/l10n/material_sr.arb
index c041c7c..0586517 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_sr.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_sr.arb
@@ -28,6 +28,7 @@
"continueButtonLabel": "Настави",
"copyButtonLabel": "Копирај",
"cutButtonLabel": "Исеци",
+ "scanTextButtonLabel": "Скенирајте текст",
"okButtonLabel": "Потврди",
"pasteButtonLabel": "Налепи",
"selectAllButtonLabel": "Изабери све",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_sv.arb b/packages/flutter_localizations/lib/src/l10n/material_sv.arb
index e73b740..5e45738 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_sv.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_sv.arb
@@ -25,6 +25,7 @@
"continueButtonLabel": "Fortsätt",
"copyButtonLabel": "Kopiera",
"cutButtonLabel": "Klipp ut",
+ "scanTextButtonLabel": "Skanna text",
"okButtonLabel": "OK",
"pasteButtonLabel": "Klistra in",
"selectAllButtonLabel": "Markera allt",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_sw.arb b/packages/flutter_localizations/lib/src/l10n/material_sw.arb
index 518629e..b31a119 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_sw.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_sw.arb
@@ -26,6 +26,7 @@
"continueButtonLabel": "Endelea",
"copyButtonLabel": "Nakili",
"cutButtonLabel": "Kata",
+ "scanTextButtonLabel": "Changanua maandishi",
"okButtonLabel": "Sawa",
"pasteButtonLabel": "Bandika",
"selectAllButtonLabel": "Chagua vyote",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_ta.arb b/packages/flutter_localizations/lib/src/l10n/material_ta.arb
index 0fbc0d4..f6fd8c3 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_ta.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_ta.arb
@@ -17,6 +17,7 @@
"reorderItemLeft": "இடப்புறம் நகர்த்தவும்",
"reorderItemRight": "வலப்புறம் நகர்த்தவும்",
"cutButtonLabel": "வெட்டு",
+ "scanTextButtonLabel": "உரையை ஸ்கேன் செய்யவும்",
"pasteButtonLabel": "ஒட்டு",
"previousMonthTooltip": "முந்தைய மாதம்",
"nextMonthTooltip": "அடுத்த மாதம்",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_te.arb b/packages/flutter_localizations/lib/src/l10n/material_te.arb
index 3922360..4220e89 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_te.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_te.arb
@@ -24,6 +24,7 @@
"closeButtonLabel": "మూసివేయండి",
"continueButtonLabel": "కొనసాగించండి",
"copyButtonLabel": "కాపీ చేయి",
+ "scanTextButtonLabel": "వచనాన్ని స్కాన్ చేయండి",
"cutButtonLabel": "కత్తిరించండి",
"okButtonLabel": "సరే",
"pasteButtonLabel": "పేస్ట్ చేయండి",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_th.arb b/packages/flutter_localizations/lib/src/l10n/material_th.arb
index 9ee0cee..a0180b3 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_th.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_th.arb
@@ -25,6 +25,7 @@
"continueButtonLabel": "ต่อไป",
"copyButtonLabel": "คัดลอก",
"cutButtonLabel": "ตัด",
+ "scanTextButtonLabel": "สแกนข้อความ",
"okButtonLabel": "ตกลง",
"pasteButtonLabel": "วาง",
"selectAllButtonLabel": "เลือกทั้งหมด",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_tl.arb b/packages/flutter_localizations/lib/src/l10n/material_tl.arb
index c154184..fbf38a1 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_tl.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_tl.arb
@@ -25,6 +25,7 @@
"continueButtonLabel": "Magpatuloy",
"copyButtonLabel": "Kopyahin",
"cutButtonLabel": "I-cut",
+ "scanTextButtonLabel": "I-scan ang text",
"okButtonLabel": "OK",
"pasteButtonLabel": "I-paste",
"selectAllButtonLabel": "Piliin lahat",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_tr.arb b/packages/flutter_localizations/lib/src/l10n/material_tr.arb
index 87566e4..b91d74d 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_tr.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_tr.arb
@@ -25,6 +25,7 @@
"continueButtonLabel": "Devam",
"copyButtonLabel": "Kopyala",
"cutButtonLabel": "Kes",
+ "scanTextButtonLabel": "Metni tara",
"okButtonLabel": "Tamam",
"pasteButtonLabel": "Yapıştır",
"selectAllButtonLabel": "Tümünü seç",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_uk.arb b/packages/flutter_localizations/lib/src/l10n/material_uk.arb
index f1edc10..fe9dcdd 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_uk.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_uk.arb
@@ -31,6 +31,7 @@
"continueButtonLabel": "Продовжити",
"copyButtonLabel": "Копіювати",
"cutButtonLabel": "Вирізати",
+ "scanTextButtonLabel": "Сканувати текст",
"okButtonLabel": "OK",
"pasteButtonLabel": "Вставити",
"selectAllButtonLabel": "Вибрати всі",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_ur.arb b/packages/flutter_localizations/lib/src/l10n/material_ur.arb
index 32b7f08..c11abd3 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_ur.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_ur.arb
@@ -25,6 +25,7 @@
"continueButtonLabel": "جاری رکھیں",
"copyButtonLabel": "کاپی کریں",
"cutButtonLabel": "کٹ کریں",
+ "scanTextButtonLabel": "متن کو اسکین کریں",
"okButtonLabel": "ٹھیک ہے",
"pasteButtonLabel": "پیسٹ کریں",
"selectAllButtonLabel": "سبھی کو منتخب کریں",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_uz.arb b/packages/flutter_localizations/lib/src/l10n/material_uz.arb
index 8ddf03c..f773009 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_uz.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_uz.arb
@@ -25,6 +25,7 @@
"continueButtonLabel": "Davom etish",
"copyButtonLabel": "Nusxa olish",
"cutButtonLabel": "Kesib olish",
+ "scanTextButtonLabel": "Matnni skanerlash",
"okButtonLabel": "OK",
"pasteButtonLabel": "Joylash",
"selectAllButtonLabel": "Hammasi",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_vi.arb b/packages/flutter_localizations/lib/src/l10n/material_vi.arb
index d4bd90f..8f57237 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_vi.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_vi.arb
@@ -25,6 +25,7 @@
"continueButtonLabel": "Tiếp tục",
"copyButtonLabel": "Sao chép",
"cutButtonLabel": "Cắt",
+ "scanTextButtonLabel": "Quét văn bản",
"okButtonLabel": "OK",
"pasteButtonLabel": "Dán",
"selectAllButtonLabel": "Chọn tất cả",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_zh.arb b/packages/flutter_localizations/lib/src/l10n/material_zh.arb
index 4e6cd30..66a28a6 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_zh.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_zh.arb
@@ -21,6 +21,7 @@
"closeButtonLabel": "关闭",
"copyButtonLabel": "复制",
"cutButtonLabel": "剪切",
+ "scanTextButtonLabel": "扫描文本",
"okButtonLabel": "确定",
"pasteButtonLabel": "粘贴",
"selectAllButtonLabel": "全选",
diff --git a/packages/flutter_localizations/lib/src/l10n/material_zu.arb b/packages/flutter_localizations/lib/src/l10n/material_zu.arb
index 76dd7b1..aae990b 100644
--- a/packages/flutter_localizations/lib/src/l10n/material_zu.arb
+++ b/packages/flutter_localizations/lib/src/l10n/material_zu.arb
@@ -25,6 +25,7 @@
"continueButtonLabel": "Qhubeka",
"copyButtonLabel": "Kopisha",
"cutButtonLabel": "Sika",
+ "scanTextButtonLabel": "Skena umbhalo",
"okButtonLabel": "KULUNGILE",
"pasteButtonLabel": "Namathisela",
"selectAllButtonLabel": "Khetha konke",
diff --git a/packages/flutter_localizations/pubspec.yaml b/packages/flutter_localizations/pubspec.yaml
index 937e181..f5ebaae 100644
--- a/packages/flutter_localizations/pubspec.yaml
+++ b/packages/flutter_localizations/pubspec.yaml
@@ -13,11 +13,11 @@
characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
clock: 1.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
collection: 1.17.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.9.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path: 1.8.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
flutter_test:
@@ -28,10 +28,10 @@
fake_async: 1.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
matcher: 0.12.16 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
-# PUBSPEC CHECKSUM: eb58
+# PUBSPEC CHECKSUM: 4c7f
diff --git a/packages/flutter_test/lib/src/_matchers_io.dart b/packages/flutter_test/lib/src/_matchers_io.dart
index 9c56372..74a3d49 100644
--- a/packages/flutter_test/lib/src/_matchers_io.dart
+++ b/packages/flutter_test/lib/src/_matchers_io.dart
@@ -24,7 +24,7 @@
assert(element.renderObject != null);
RenderObject renderObject = element.renderObject!;
while (!renderObject.isRepaintBoundary) {
- renderObject = renderObject.parent! as RenderObject;
+ renderObject = renderObject.parent!;
}
assert(!renderObject.debugNeedsPaint);
final OffsetLayer layer = renderObject.debugLayer! as OffsetLayer;
@@ -124,7 +124,7 @@
image.dispose();
}
}
- }, additionalTime: const Duration(minutes: 1));
+ });
}
@override
diff --git a/packages/flutter_test/lib/src/_matchers_web.dart b/packages/flutter_test/lib/src/_matchers_web.dart
index 71a78c3..749b571 100644
--- a/packages/flutter_test/lib/src/_matchers_web.dart
+++ b/packages/flutter_test/lib/src/_matchers_web.dart
@@ -77,7 +77,7 @@
} on TestFailure catch (ex) {
return ex.message;
}
- }, additionalTime: const Duration(seconds: 22));
+ });
_renderElement(view, _findRepaintBoundary(e));
return result;
}
@@ -93,7 +93,7 @@
assert(element.renderObject != null);
RenderObject renderObject = element.renderObject!;
while (!renderObject.isRepaintBoundary) {
- renderObject = renderObject.parent! as RenderObject;
+ renderObject = renderObject.parent!;
}
return renderObject;
}
diff --git a/packages/flutter_test/lib/src/animation_sheet.dart b/packages/flutter_test/lib/src/animation_sheet.dart
index 9f5a64e..2297328 100644
--- a/packages/flutter_test/lib/src/animation_sheet.dart
+++ b/packages/flutter_test/lib/src/animation_sheet.dart
@@ -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 'dart:math' as math;
import 'dart:ui' as ui;
import 'package:flutter/foundation.dart';
@@ -136,7 +135,7 @@
/// The frame is only recorded if the `recording` argument is true, or during
/// a procedure that is wrapped within [recording]. In either case, the
/// painted result of each frame will be stored and later available for
- /// [display]. If neither condition is met, the frames are not recorded, which
+ /// [collate]. If neither condition is met, the frames are not recorded, which
/// is useful during setup phases.
///
/// The `child` must not be null.
@@ -158,113 +157,6 @@
);
}
- /// Constructs a widget that renders the recorded frames in an animation sheet.
- ///
- /// The resulting widget takes as much space as its parent allows, which is
- /// usually the screen size. It is then filled with all recorded frames, each
- /// having a size specified by [frameSize], chronologically from top-left to
- /// bottom-right in a row-major order.
- ///
- /// This widget does not check whether its size fits all recorded frames.
- /// Having too many frames can cause overflow errors, while having too few can
- /// waste the size of golden files. Therefore you should usually adjust the
- /// viewport size to [sheetSize] before calling this method.
- ///
- /// The `key` is applied to the root widget.
- ///
- /// This method can only be called if at least one frame has been recorded.
- ///
- /// The [display] is the legacy way of acquiring the output for comparison.
- /// It is not recommended because it requires more boilerplate, and produces
- /// a much large image than necessary: each pixel is rendered in 3x3 pixels
- /// without higher definition. Use [collate] instead.
- ///
- /// Using this way includes the following steps:
- ///
- /// * Create an instance of this class.
- /// * Pump frames that render the target widget wrapped in [record]. Every frame
- /// that has `recording` being true will be recorded.
- /// * Adjust the size of the test viewport to the [sheetSize] (see the
- /// documentation of [sheetSize] for more information).
- /// * Pump a frame that renders [display], which shows all recorded frames in an
- /// animation sheet, and can be matched against the golden test.
- ///
- /// {@tool snippet}
- /// The following example shows how to record an animation sheet of an [InkWell]
- /// being pressed then released.
- ///
- /// ```dart
- /// testWidgets('Inkwell animation sheet', (WidgetTester tester) async {
- /// // Create instance
- /// final AnimationSheetBuilder animationSheet = AnimationSheetBuilder(frameSize: const Size(48, 24));
- ///
- /// final Widget target = Material(
- /// child: Directionality(
- /// textDirection: TextDirection.ltr,
- /// child: InkWell(
- /// splashColor: Colors.blue,
- /// onTap: () {},
- /// ),
- /// ),
- /// );
- ///
- /// // Optional: setup before recording (`recording` is false)
- /// await tester.pumpWidget(animationSheet.record(
- /// target,
- /// recording: false,
- /// ));
- ///
- /// final TestGesture gesture = await tester.startGesture(tester.getCenter(find.byType(InkWell)));
- ///
- /// // Start recording (`recording` is true)
- /// await tester.pumpFrames(animationSheet.record(
- /// target,
- /// recording: true,
- /// ), const Duration(seconds: 1));
- ///
- /// await gesture.up();
- ///
- /// await tester.pumpFrames(animationSheet.record(
- /// target,
- /// recording: true,
- /// ), const Duration(seconds: 1));
- ///
- /// // Adjust view port size
- /// tester.binding.setSurfaceSize(animationSheet.sheetSize());
- ///
- /// // Display
- /// final Widget display = await animationSheet.display();
- /// await tester.pumpWidget(display);
- ///
- /// // Compare against golden file
- /// await expectLater(
- /// find.byWidget(display),
- /// matchesGoldenFile('inkwell.press.animation.png'),
- /// );
- /// }, skip: isBrowser); // Animation sheet does not support browser https://github.com/flutter/flutter/issues/56001
- /// ```
- /// {@end-tool}
- @Deprecated(
- 'Use AnimationSheetBuilder.collate instead. '
- 'This feature was deprecated after v2.3.0-13.0.pre.',
- )
- Future<Widget> display({Key? key}) async {
- assert(_recordedFrames.isNotEmpty);
- final List<ui.Image> frames = await _frames;
- return _CellSheet(
- key: key,
- cellSize: frameSize,
- children: frames.map((ui.Image image) => RawImage(
- image: image.clone(),
- width: frameSize.width,
- height: frameSize.height,
- // Disable quality enhancement because the point of this class is to
- // precisely record what the widget looks like.
- filterQuality: ui.FilterQuality.none,
- )).toList(),
- );
- }
-
/// Returns an result image by putting all frames together in a table.
///
/// This method returns a table of captured frames, `cellsPerRow` images
@@ -277,39 +169,6 @@
'No frames are collected. Have you forgot to set `recording` to true?');
return _collateFrames(frames, frameSize, cellsPerRow);
}
-
- /// Returns the smallest size that can contain all recorded frames.
- ///
- /// This is used to adjust the viewport during unit tests, i.e. the size of
- /// virtual screen. Having too many frames recorded than the default viewport
- /// size can contain will lead to overflow errors, while having too few frames
- /// means the golden file might be larger than necessary.
- ///
- /// The [sheetSize] returns the smallest possible size by placing the
- /// recorded frames, each of which has a size specified by [frameSize], in a
- /// row-major grid with a maximum width specified by `maxWidth`, and returns
- /// the size of that grid.
- ///
- /// Setting the viewport size during a widget test usually involves
- /// [TestWidgetsFlutterBinding.setSurfaceSize] and [WidgetTester.binding].
- ///
- /// The `maxWidth` defaults to the width of the default viewport, 800.0.
- ///
- /// This method can only be called if at least one frame has been recorded.
- @Deprecated(
- 'The `sheetSize` is only useful for `display`, which should be migrated to `collate`. '
- 'This feature was deprecated after v2.3.0-13.0.pre.',
- )
- Size sheetSize({double maxWidth = _kDefaultTestViewportWidth}) {
- assert(_recordedFrames.isNotEmpty);
- final int cellsPerRow = (maxWidth / frameSize.width).floor();
- final int rowNum = (_recordedFrames.length / cellsPerRow).ceil();
- final double width = math.min(cellsPerRow, _recordedFrames.length) * frameSize.width;
- return Size(width, frameSize.height * rowNum);
- }
-
- // The width of _kDefaultTestViewportSize in [TestViewConfiguration].
- static const double _kDefaultTestViewportWidth = 800.0;
}
typedef _RecordedHandler = void Function(Future<ui.Image> image);
@@ -446,45 +305,6 @@
return image;
}
-// Layout children in a grid of fixed-sized cells.
-//
-// The sheet fills up as much space as the parent allows. The cells are
-// positioned from top left to bottom right in a row-major order.
-class _CellSheet extends StatelessWidget {
- _CellSheet({
- super.key,
- required this.cellSize,
- required this.children,
- }) : assert(children.isNotEmpty);
-
- final Size cellSize;
- final List<Widget> children;
-
- @override
- Widget build(BuildContext context) {
- return LayoutBuilder(builder: (BuildContext context, BoxConstraints constraints) {
- final double rowWidth = constraints.biggest.width;
- final int cellsPerRow = (rowWidth / cellSize.width).floor();
- final List<Widget> rows = <Widget>[];
- for (int rowStart = 0; rowStart < children.length; rowStart += cellsPerRow) {
- final Iterable<Widget> rowTargets = children.sublist(rowStart, math.min(rowStart + cellsPerRow, children.length));
- rows.add(Row(
- textDirection: TextDirection.ltr,
- children: rowTargets.map((Widget target) => SizedBox.fromSize(
- size: cellSize,
- child: target,
- )).toList(),
- ));
- }
- return Column(
- textDirection: TextDirection.ltr,
- crossAxisAlignment: CrossAxisAlignment.start,
- children: rows,
- );
- });
- }
-}
-
class _RenderRootableRepaintBoundary extends RenderRepaintBoundary {
// Like [toImage], but captures an image of all layers (composited by
// RenderView and its children) clipped by the region of this object.
diff --git a/packages/flutter_test/lib/src/binding.dart b/packages/flutter_test/lib/src/binding.dart
index a8d16b1..23caf1f 100644
--- a/packages/flutter_test/lib/src/binding.dart
+++ b/packages/flutter_test/lib/src/binding.dart
@@ -310,19 +310,6 @@
@protected
bool get registerTestTextInput => true;
- /// This method has no effect.
- ///
- /// This method was previously used to change the timeout of the test. However,
- /// in practice having short timeouts was found to be nothing but trouble,
- /// primarily being a cause flakes rather than helping debug tests.
- ///
- /// For this reason, this method has been deprecated.
- @Deprecated(
- 'This method has no effect. '
- 'This feature was deprecated after v2.6.0-1.0.pre.'
- )
- void addTime(Duration duration) { }
-
/// Delay for `duration` of time.
///
/// In the automated test environment ([AutomatedTestWidgetsFlutterBinding],
@@ -465,17 +452,7 @@
/// are required to wait for the returned future to complete before calling
/// this method again. Attempts to do otherwise will result in a
/// [TestFailure] error being thrown.
- ///
- /// The `additionalTime` argument was previously used with
- /// [AutomatedTestWidgetsFlutterBinding.addTime] but now has no effect.
- Future<T?> runAsync<T>(
- Future<T> Function() callback, {
- @Deprecated(
- 'This parameter has no effect. '
- 'This feature was deprecated after v2.6.0-1.0.pre.'
- )
- Duration additionalTime = const Duration(milliseconds: 1000),
- });
+ Future<T?> runAsync<T>(Future<T> Function() callback);
/// Artificially calls dispatchLocalesChanged on the Widget binding,
/// then flushes microtasks.
@@ -779,13 +756,6 @@
Future<void> Function() testBody,
VoidCallback invariantTester, {
String description = '',
- @Deprecated(
- 'This parameter has no effect. Use the `timeout` parameter on `testWidgets` instead. '
- 'This feature was deprecated after v2.6.0-1.0.pre.'
- )
- // TODO(pdblasi-google): Do not remove until https://github.com/flutter/flutter/issues/124346
- // is complete, as this removal will cascade into `integration_test`
- Duration? timeout,
});
/// This is called during test execution before and after the body has been
@@ -1255,7 +1225,6 @@
}
_phase = newPhase;
if (hasScheduledFrame) {
- addTime(const Duration(milliseconds: 500));
_currentFakeAsync!.flushMicrotasks();
handleBeginFrame(Duration(
milliseconds: _clock!.now().millisecondsSinceEpoch,
@@ -1269,10 +1238,7 @@
}
@override
- Future<T?> runAsync<T>(
- Future<T> Function() callback, {
- Duration additionalTime = const Duration(milliseconds: 1000),
- }) {
+ Future<T?> runAsync<T>(Future<T> Function() callback) {
assert(() {
if (_pendingAsyncTasks == null) {
return true;
@@ -1299,8 +1265,6 @@
),
);
- addTime(additionalTime);
-
return realAsyncZone.run<Future<T?>>(() {
final Completer<T?> result = Completer<T?>();
_pendingAsyncTasks = Completer<void>();
@@ -1454,13 +1418,6 @@
Future<void> Function() testBody,
VoidCallback invariantTester, {
String description = '',
- @Deprecated(
- 'This parameter has no effect. Use the `timeout` parameter on `testWidgets` instead. '
- 'This feature was deprecated after v2.6.0-1.0.pre.'
- )
- // TODO(pdblasi-google): Do not remove until https://github.com/flutter/flutter/issues/124346
- // is complete, as this removal will cascade into `integration_test`
- Duration? timeout,
}) {
assert(!inTest);
assert(_currentFakeAsync == null);
@@ -1965,10 +1922,7 @@
}
@override
- Future<T?> runAsync<T>(
- Future<T> Function() callback, {
- Duration additionalTime = const Duration(milliseconds: 1000),
- }) async {
+ Future<T?> runAsync<T>(Future<T> Function() callback) async {
assert(() {
if (!_runningAsyncTasks) {
return true;
@@ -2002,13 +1956,6 @@
Future<void> Function() testBody,
VoidCallback invariantTester, {
String description = '',
- @Deprecated(
- 'This parameter has no effect. Use the `timeout` parameter on `testWidgets` instead. '
- 'This feature was deprecated after v2.6.0-1.0.pre.'
- )
- // TODO(pdblasi-google): Do not remove until https://github.com/flutter/flutter/issues/124346
- // is complete, as this removal will cascade into `integration_test`
- Duration? timeout,
}) {
assert(!inTest);
_inTest = true;
diff --git a/packages/flutter_test/lib/src/controller.dart b/packages/flutter_test/lib/src/controller.dart
index bdc1ab9..4033ba0 100644
--- a/packages/flutter_test/lib/src/controller.dart
+++ b/packages/flutter_test/lib/src/controller.dart
@@ -87,7 +87,7 @@
RenderObject? renderObject = element.findRenderObject();
SemanticsNode? result = renderObject?.debugSemantics;
while (renderObject != null && (result == null || result.isMergedIntoParent)) {
- renderObject = renderObject.parent as RenderObject?;
+ renderObject = renderObject.parent;
result = renderObject?.debugSemantics;
}
if (result == null) {
@@ -366,7 +366,7 @@
final RenderObject object = element.renderObject!;
RenderObject current = object;
while (current.debugLayer == null) {
- current = current.parent! as RenderObject;
+ current = current.parent!;
}
final ContainerLayer layer = current.debugLayer!;
return _walkLayers(layer);
diff --git a/packages/flutter_test/lib/src/matchers.dart b/packages/flutter_test/lib/src/matchers.dart
index 0c287d1..3cc1bb6 100644
--- a/packages/flutter_test/lib/src/matchers.dart
+++ b/packages/flutter_test/lib/src/matchers.dart
@@ -2054,7 +2054,7 @@
Uint8List.view(referenceBytes.buffer),
);
return countDifferentPixels == 0 ? null : 'does not match on $countDifferentPixels pixels';
- }, additionalTime: const Duration(minutes: 1));
+ });
}
@override
diff --git a/packages/flutter_test/lib/src/widget_tester.dart b/packages/flutter_test/lib/src/widget_tester.dart
index 0a26dfc..8cd6d50 100644
--- a/packages/flutter_test/lib/src/widget_tester.dart
+++ b/packages/flutter_test/lib/src/widget_tester.dart
@@ -93,9 +93,7 @@
/// `test` package. If set, it should be relatively large (minutes). It defaults
/// to ten minutes for tests run by `flutter test`, and is unlimited for tests
/// run by `flutter run`; specifically, it defaults to
-/// [TestWidgetsFlutterBinding.defaultTestTimeout]. (The `initialTimeout`
-/// parameter has no effect. It was previously used with
-/// [TestWidgetsFlutterBinding.addTime] but that feature was removed.)
+/// [TestWidgetsFlutterBinding.defaultTestTimeout].
///
/// If the `semanticsEnabled` parameter is set to `true`,
/// [WidgetTester.ensureSemantics] will have been called before the tester is
@@ -115,11 +113,6 @@
/// If the [tags] are passed, they declare user-defined tags that are implemented by
/// the `test` package.
///
-/// See also:
-///
-/// * [AutomatedTestWidgetsFlutterBinding.addTime] to learn more about
-/// timeout and how to manually increase timeouts.
-///
/// ## Sample code
///
/// ```dart
@@ -135,11 +128,6 @@
WidgetTesterCallback callback, {
bool? skip,
test_package.Timeout? timeout,
- @Deprecated(
- 'This parameter has no effect. Use `timeout` instead. '
- 'This feature was deprecated after v2.6.0-1.0.pre.'
- )
- Duration? initialTimeout,
bool semanticsEnabled = true,
TestVariant<Object?> variant = const DefaultTestVariant(),
dynamic tags,
@@ -182,7 +170,6 @@
},
tester._endOfTestVerifications,
description: combinedDescription,
- timeout: initialTimeout,
);
},
skip: skip,
@@ -826,8 +813,12 @@
/// your widget tree, then await that future inside [callback].
Future<T?> runAsync<T>(
Future<T> Function() callback, {
+ @Deprecated(
+ 'This is no longer supported and has no effect. '
+ 'This feature was deprecated after v3.12.0-1.1.pre.'
+ )
Duration additionalTime = const Duration(milliseconds: 1000),
- }) => binding.runAsync<T?>(callback, additionalTime: additionalTime);
+ }) => binding.runAsync<T?>(callback);
/// Whether there are any transient callbacks scheduled.
///
diff --git a/packages/flutter_test/pubspec.yaml b/packages/flutter_test/pubspec.yaml
index c2c8024..fc8a02e 100644
--- a/packages/flutter_test/pubspec.yaml
+++ b/packages/flutter_test/pubspec.yaml
@@ -12,7 +12,7 @@
# We depend on very specific internal implementation details of the
# 'test' package, which change between versions, so when upgrading
# this, make sure the tests are still running correctly.
- test_api: 0.6.0
+ test_api: 0.6.1
matcher: 0.12.16
# Used by golden file comparator
@@ -25,7 +25,7 @@
# We import stack_trace because the test packages uses it and we
# need to be able to unmangle the stack traces that it passed to
# stack_trace. See https://github.com/dart-lang/test/issues/590
- stack_trace: 1.11.0
+ stack_trace: 1.11.1
# Used by globalToLocal et al.
vector_math: 2.1.4
@@ -34,15 +34,15 @@
boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
collection: 1.17.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.9.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
file: 6.1.4
-# PUBSPEC CHECKSUM: 2b12
+# PUBSPEC CHECKSUM: 4039
diff --git a/packages/flutter_test/test/window_test.dart b/packages/flutter_test/test/window_test.dart
index 495004d..144890c 100644
--- a/packages/flutter_test/test/window_test.dart
+++ b/packages/flutter_test/test/window_test.dart
@@ -243,7 +243,6 @@
class TestObserver with WidgetsBindingObserver {
List<Locale>? locales;
- Locale? locale;
@override
void didChangeLocales(List<Locale>? locales) {
diff --git a/packages/flutter_tools/bin/xcode_backend.dart b/packages/flutter_tools/bin/xcode_backend.dart
index 9d4e46e..0486a87 100644
--- a/packages/flutter_tools/bin/xcode_backend.dart
+++ b/packages/flutter_tools/bin/xcode_backend.dart
@@ -63,11 +63,6 @@
}
}
- bool existsDir(String path) {
- final Directory dir = Directory(path);
- return dir.existsSync();
- }
-
bool existsFile(String path) {
final File file = File(path);
return file.existsSync();
diff --git a/packages/flutter_tools/lib/executable.dart b/packages/flutter_tools/lib/executable.dart
index ab81912..2fb826f 100644
--- a/packages/flutter_tools/lib/executable.dart
+++ b/packages/flutter_tools/lib/executable.dart
@@ -28,7 +28,6 @@
import 'src/commands/downgrade.dart';
import 'src/commands/drive.dart';
import 'src/commands/emulators.dart';
-import 'src/commands/format.dart';
import 'src/commands/generate.dart';
import 'src/commands/generate_localizations.dart';
import 'src/commands/ide_config.dart';
@@ -200,7 +199,6 @@
signals: globals.signals,
),
EmulatorsCommand(),
- FormatCommand(),
GenerateCommand(),
GenerateLocalizationsCommand(
fileSystem: globals.fs,
diff --git a/packages/flutter_tools/lib/src/android/gradle_errors.dart b/packages/flutter_tools/lib/src/android/gradle_errors.dart
index 17c79e7..4044baa 100644
--- a/packages/flutter_tools/lib/src/android/gradle_errors.dart
+++ b/packages/flutter_tools/lib/src/android/gradle_errors.dart
@@ -83,6 +83,7 @@
zipExceptionHandler,
incompatibleJavaAndGradleVersionsHandler,
remoteTerminatedHandshakeHandler,
+ couldNotOpenCacheDirectoryHandler,
];
const String _boxTitle = 'Flutter Fix';
@@ -715,3 +716,22 @@
},
eventLabel: 'remote-terminated-handshake',
);
+
+@visibleForTesting
+final GradleHandledError couldNotOpenCacheDirectoryHandler = GradleHandledError(
+ test: (String line) => line.contains('> Could not open cache directory '),
+ handler: ({
+ required String line,
+ required FlutterProject project,
+ required bool usesAndroidX,
+ required bool multidexEnabled,
+ }) async {
+ globals.printError(
+ '${globals.logger.terminal.warningMark} '
+ 'Gradle threw an error while resolving dependencies.'
+ );
+
+ return GradleBuildStatus.retry;
+ },
+ eventLabel: 'could-not-open-cache-directory',
+);
diff --git a/packages/flutter_tools/lib/src/base/user_messages.dart b/packages/flutter_tools/lib/src/base/user_messages.dart
index 8441db2..1c13db1 100644
--- a/packages/flutter_tools/lib/src/base/user_messages.dart
+++ b/packages/flutter_tools/lib/src/base/user_messages.dart
@@ -183,10 +183,10 @@
' sudo xcodebuild -runFirstLaunch';
String get xcodeMissing =>
'Xcode not installed; this is necessary for iOS and macOS development.\n'
- 'Download at https://developer.apple.com/xcode/download/.';
+ 'Download at https://developer.apple.com/xcode/.';
String get xcodeIncomplete =>
'Xcode installation is incomplete; a full installation is necessary for iOS and macOS development.\n'
- 'Download at: https://developer.apple.com/xcode/download/\n'
+ 'Download at: https://developer.apple.com/xcode/\n'
'Or install Xcode via the App Store.\n'
'Once installed, run:\n'
' sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer\n'
diff --git a/packages/flutter_tools/lib/src/base/utils.dart b/packages/flutter_tools/lib/src/base/utils.dart
index 1aa9130..46d0ef3 100644
--- a/packages/flutter_tools/lib/src/base/utils.dart
+++ b/packages/flutter_tools/lib/src/base/utils.dart
@@ -59,7 +59,8 @@
if (str.isEmpty) {
return str;
}
- return toBeginningOfSentenceCase(str, locale)!;
+ // TODO(christopherfujino): Remove this check after the next release of intl
+ return ArgumentError.checkNotNull(toBeginningOfSentenceCase(str, locale));
}
/// Converts `foo_bar` to `Foo Bar`.
diff --git a/packages/flutter_tools/lib/src/build_info.dart b/packages/flutter_tools/lib/src/build_info.dart
index 5260a3d..053197c 100644
--- a/packages/flutter_tools/lib/src/build_info.dart
+++ b/packages/flutter_tools/lib/src/build_info.dart
@@ -38,7 +38,7 @@
this.webRenderer = WebRendererMode.auto,
required this.treeShakeIcons,
this.performanceMeasurementFile,
- this.dartDefineConfigJsonMap,
+ this.dartDefineConfigJsonMap = const <String, Object?>{},
this.packagesPath = '.dart_tool/package_config.json', // TODO(zanderso): make this required and remove the default.
this.nullSafetyMode = NullSafetyMode.sound,
this.codeSizeDirectory,
@@ -144,7 +144,7 @@
///
/// An additional field `dartDefineConfigJsonMap` is provided to represent the native JSON value of the configuration file
///
- final Map<String, Object>? dartDefineConfigJsonMap;
+ final Map<String, Object?> dartDefineConfigJsonMap;
/// If provided, an output directory where one or more v8-style heap snapshots
/// will be written for code size profiling.
@@ -267,7 +267,7 @@
/// Fields that are `null` are excluded from this configuration.
Map<String, String> toEnvironmentConfig() {
final Map<String, String> map = <String, String>{};
- dartDefineConfigJsonMap?.forEach((String key, Object value) {
+ dartDefineConfigJsonMap.forEach((String key, Object? value) {
map[key] = '$value';
});
final Map<String, String> environmentMap = <String, String>{
@@ -327,17 +327,15 @@
for (final String projectArg in androidProjectArgs)
'-P$projectArg',
];
- if (dartDefineConfigJsonMap != null) {
- final Iterable<String> gradleConfKeys = result.map((final String gradleConf) => gradleConf.split('=')[0].substring(2));
- dartDefineConfigJsonMap!.forEach((String key, Object value) {
- if (gradleConfKeys.contains(key)) {
- globals.printWarning(
- 'The key: [$key] already exists, you cannot use gradle variables that have been used by the system!');
- } else {
- result.add('-P$key=$value');
- }
- });
- }
+ final Iterable<String> gradleConfKeys = result.map((final String gradleConf) => gradleConf.split('=')[0].substring(2));
+ dartDefineConfigJsonMap.forEach((String key, Object? value) {
+ if (gradleConfKeys.contains(key)) {
+ globals.printWarning(
+ 'The key: [$key] already exists, you cannot use gradle variables that have been used by the system!');
+ } else {
+ result.add('-P$key=$value');
+ }
+ });
return result;
}
}
diff --git a/packages/flutter_tools/lib/src/bundle_builder.dart b/packages/flutter_tools/lib/src/bundle_builder.dart
index afa1530..680eac7 100644
--- a/packages/flutter_tools/lib/src/bundle_builder.dart
+++ b/packages/flutter_tools/lib/src/bundle_builder.dart
@@ -21,7 +21,6 @@
import 'globals.dart' as globals;
import 'project.dart';
-
/// Provides a `build` method that builds the bundle.
class BundleBuilder {
/// Builds the bundle for the given target platform.
diff --git a/packages/flutter_tools/lib/src/commands/assemble.dart b/packages/flutter_tools/lib/src/commands/assemble.dart
index ba2b528..1f9a212 100644
--- a/packages/flutter_tools/lib/src/commands/assemble.dart
+++ b/packages/flutter_tools/lib/src/commands/assemble.dart
@@ -258,7 +258,7 @@
results[kExtraGenSnapshotOptions] = (argumentResults[FlutterOptions.kExtraGenSnapshotOptions] as List<String>).join(',');
}
- final Map<String, Object>? defineConfigJsonMap = extractDartDefineConfigJsonMap();
+ final Map<String, Object?> defineConfigJsonMap = extractDartDefineConfigJsonMap();
final List<String> dartDefines = extractDartDefines(defineConfigJsonMap: defineConfigJsonMap);
if (dartDefines.isNotEmpty){
results[kDartDefines] = dartDefines.join(',');
diff --git a/packages/flutter_tools/lib/src/commands/doctor.dart b/packages/flutter_tools/lib/src/commands/doctor.dart
index 43c1f31..7e7e3ea 100644
--- a/packages/flutter_tools/lib/src/commands/doctor.dart
+++ b/packages/flutter_tools/lib/src/commands/doctor.dart
@@ -33,7 +33,6 @@
@override
Future<FlutterCommandResult> runCommand() async {
- globals.flutterVersion.fetchTagsAndUpdate();
if (argResults?.wasParsed('check-for-remote-artifacts') ?? false) {
final String engineRevision = stringArg('check-for-remote-artifacts')!;
if (engineRevision.startsWith(RegExp(r'[a-f0-9]{1,40}'))) {
diff --git a/packages/flutter_tools/lib/src/commands/downgrade.dart b/packages/flutter_tools/lib/src/commands/downgrade.dart
index a27482a..a58b75c 100644
--- a/packages/flutter_tools/lib/src/commands/downgrade.dart
+++ b/packages/flutter_tools/lib/src/commands/downgrade.dart
@@ -92,7 +92,10 @@
String workingDirectory = Cache.flutterRoot!;
if (argResults!.wasParsed('working-directory')) {
workingDirectory = stringArg('working-directory')!;
- _flutterVersion = FlutterVersion(workingDirectory: workingDirectory);
+ _flutterVersion = FlutterVersion(
+ fs: _fileSystem!,
+ flutterRoot: workingDirectory,
+ );
}
final String currentChannel = _flutterVersion!.channel;
diff --git a/packages/flutter_tools/lib/src/commands/format.dart b/packages/flutter_tools/lib/src/commands/format.dart
deleted file mode 100644
index c4ea165..0000000
--- a/packages/flutter_tools/lib/src/commands/format.dart
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2014 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'package:args/args.dart';
-
-import '../base/common.dart';
-import '../runner/flutter_command.dart';
-
-class FormatCommand extends FlutterCommand {
- FormatCommand();
-
- @override
- ArgParser argParser = ArgParser.allowAnything();
-
- @override
- final String name = 'format';
-
- @override
- List<String> get aliases => const <String>['dartfmt'];
-
- @override
- String get description => deprecationWarning;
-
- @override
- final bool hidden = true;
-
- @override
- String get deprecationWarning {
- return 'The "format" command is deprecated. Please use the "dart format" '
- 'sub-command instead, which has the same command-line usage as '
- '"flutter format".\n';
- }
-
- @override
- Future<FlutterCommandResult> runCommand() async {
- throwToolExit(deprecationWarning);
- }
-}
diff --git a/packages/flutter_tools/lib/src/commands/generate_localizations.dart b/packages/flutter_tools/lib/src/commands/generate_localizations.dart
index a7931f0..452dc19 100644
--- a/packages/flutter_tools/lib/src/commands/generate_localizations.dart
+++ b/packages/flutter_tools/lib/src/commands/generate_localizations.dart
@@ -5,6 +5,7 @@
import 'package:process/process.dart';
import '../artifacts.dart';
+import '../base/common.dart';
import '../base/file_system.dart';
import '../base/logger.dart';
import '../localizations/gen_l10n.dart';
@@ -217,6 +218,10 @@
@override
Future<FlutterCommandResult> runCommand() async {
+ // Validate the rest of the args.
+ if (argResults!.rest.isNotEmpty) {
+ throwToolExit('Unexpected positional argument "${argResults!.rest.first}".');
+ }
// Keep in mind that this is also defined in the following locations:
// 1. flutter_tools/lib/src/build_system/targets/localizations.dart
// 2. flutter_tools/test/general.shard/build_system/targets/localizations_test.dart
diff --git a/packages/flutter_tools/lib/src/commands/update_packages.dart b/packages/flutter_tools/lib/src/commands/update_packages.dart
index bae6680..5d24005 100644
--- a/packages/flutter_tools/lib/src/commands/update_packages.dart
+++ b/packages/flutter_tools/lib/src/commands/update_packages.dart
@@ -38,8 +38,6 @@
'url_launcher_android': '6.0.17',
// https://github.com/flutter/flutter/issues/115660
'archive': '3.3.2',
- // https://github.com/flutter/flutter/issues/116376
- 'path_provider_android': '2.0.21',
};
class UpdatePackagesCommand extends FlutterCommand {
@@ -51,6 +49,14 @@
'This will actually modify the pubspec.yaml files in your checkout.',
negatable: false,
)
+ ..addOption(
+ 'cherry-pick-package',
+ help: 'Attempt to update only the specified package. The "-cherry-pick-version" version must be specified also.',
+ )
+ ..addOption(
+ 'cherry-pick-version',
+ help: 'Attempt to update the package to the specified version. The "--cherry-pick-package" option must be specified also.',
+ )
..addFlag(
'paths',
help: 'Finds paths in the dependency chain leading from package specified '
@@ -182,7 +188,8 @@
final bool isVerifyOnly = boolArg('verify-only');
final bool isConsumerOnly = boolArg('consumer-only');
final bool offline = boolArg('offline');
- final bool doUpgrade = forceUpgrade || isPrintPaths || isPrintTransitiveClosure;
+ final String? cherryPickPackage = stringArg('cherry-pick-package');
+ final String? cherryPickVersion = stringArg('cherry-pick-version');
if (boolArg('crash')) {
throw StateError('test crash please ignore.');
@@ -194,6 +201,54 @@
);
}
+ if (forceUpgrade && cherryPickPackage != null) {
+ throwToolExit(
+ '--force-upgrade cannot be used with the --cherry-pick-package flag'
+ );
+ }
+
+ if (forceUpgrade && isPrintPaths) {
+ throwToolExit(
+ '--force-upgrade cannot be used with the --paths flag'
+ );
+ }
+
+ if (forceUpgrade && isPrintTransitiveClosure) {
+ throwToolExit(
+ '--force-upgrade cannot be used with the --transitive-closure flag'
+ );
+ }
+
+ if (cherryPickPackage != null && offline) {
+ throwToolExit(
+ '--cherry-pick-package cannot be used with the --offline flag'
+ );
+ }
+
+ if (cherryPickPackage != null && cherryPickVersion == null) {
+ throwToolExit(
+ '--cherry-pick-version is required when using --cherry-pick-package flag'
+ );
+ }
+
+ if (isPrintPaths && (stringArg('from') == null || stringArg('to') == null)) {
+ throwToolExit(
+ 'The --from and --to flags are required when using the --paths flag'
+ );
+ }
+
+ if (!isPrintPaths && (stringArg('from') != null || stringArg('to') != null)) {
+ throwToolExit(
+ 'The --from and --to flags are only allowed when using the --paths flag'
+ );
+ }
+
+ if (isPrintTransitiveClosure && isPrintPaths) {
+ throwToolExit(
+ 'The --transitive-closure flag cannot be used with the --paths flag'
+ );
+ }
+
// "consumer" packages are those that constitute our public API (e.g. flutter, flutter_test, flutter_driver, flutter_localizations, integration_test).
if (isConsumerOnly) {
if (!isPrintTransitiveClosure) {
@@ -216,7 +271,7 @@
return FlutterCommandResult.success();
}
- if (doUpgrade) {
+ if (forceUpgrade) {
// This feature attempts to collect all the packages used across all the
// pubspec.yamls in the repo (including via transitive dependencies), and
// find the latest version of each that can be used while keeping each
@@ -235,9 +290,38 @@
explicitDependencies: explicitDependencies,
allDependencies: allDependencies,
specialDependencies: specialDependencies,
- doUpgrade: doUpgrade,
+ printPaths: forceUpgrade || isPrintPaths || isPrintTransitiveClosure || cherryPickPackage != null,
);
+ final Iterable<PubspecDependency> baseDependencies;
+ if (cherryPickPackage != null) {
+ if (!allDependencies.containsKey(cherryPickPackage)) {
+ throwToolExit(
+ 'Package "$cherryPickPackage" is not currently a dependency, and therefore cannot be upgraded.'
+ );
+ }
+ if (cherryPickVersion != null) {
+ globals.printStatus('Pinning package "$cherryPickPackage" to version "$cherryPickVersion"...');
+ } else {
+ globals.printStatus('Upgrading package "$cherryPickPackage"...');
+ }
+ final List<PubspecDependency> adjustedDependencies = <PubspecDependency>[];
+ for (final String package in allDependencies.keys) {
+ if (package == cherryPickPackage) {
+ assert(cherryPickVersion != null);
+ final PubspecDependency pubspec = allDependencies[cherryPickPackage]!;
+ adjustedDependencies.add(pubspec.copyWith(version: cherryPickVersion));
+ } else {
+ adjustedDependencies.add(allDependencies[package]!);
+ }
+ }
+ baseDependencies = adjustedDependencies;
+ } else if (forceUpgrade) {
+ baseDependencies = explicitDependencies.values;
+ } else {
+ baseDependencies = allDependencies.values;
+ }
+
// Now that we have all the dependencies we care about, we are going to
// create a fake package and then run either "pub upgrade", if requested,
// followed by "pub get" on it. If upgrading, the pub tool will attempt to
@@ -246,12 +330,14 @@
// attempt to download any necessary package versions to the pub cache to
// warm the cache.
final PubDependencyTree tree = PubDependencyTree(); // object to collect results
- await _generateFakePackage(
+ await _pubGetAllDependencies(
tempDir: _syntheticPackageDir,
- dependencies: doUpgrade ? explicitDependencies.values : allDependencies.values,
+ dependencies: baseDependencies,
pubspecs: pubspecs,
tree: tree,
- doUpgrade: doUpgrade,
+ doUpgrade: forceUpgrade,
+ isolateEnvironment: forceUpgrade || isPrintPaths || isPrintTransitiveClosure || cherryPickPackage != null,
+ reportDependenciesToTree: forceUpgrade || isPrintPaths || isPrintTransitiveClosure || cherryPickPackage != null,
);
// Only delete the synthetic package if it was done in a temp directory
@@ -259,18 +345,31 @@
_syntheticPackageDir.deleteSync(recursive: true);
}
- if (doUpgrade) {
- final bool done = _upgradePubspecs(
+ if (forceUpgrade || isPrintTransitiveClosure || isPrintPaths || cherryPickPackage != null) {
+ _processPubspecs(
tree: tree,
pubspecs: pubspecs,
- explicitDependencies: explicitDependencies,
specialDependencies: specialDependencies,
);
- if (done) {
- // Complete early if we were just printing data.
+ if (isPrintTransitiveClosure) {
+ tree._dependencyTree.forEach((String from, Set<String> to) {
+ globals.printStatus('$from -> $to');
+ });
return FlutterCommandResult.success();
}
+
+ if (isPrintPaths) {
+ showDependencyPaths(from: stringArg('from')!, to: stringArg('to')!, tree: tree);
+ return FlutterCommandResult.success();
+ }
+
+ globals.printStatus('Updating workspace...');
+ _updatePubspecs(
+ tree: tree,
+ pubspecs: pubspecs,
+ specialDependencies: specialDependencies,
+ );
}
await _runPubGetOnPackages(packages);
@@ -306,8 +405,9 @@
// we need to run update-packages to recapture the transitive deps.
globals.printWarning(
'Warning: pubspec in ${directory.path} has updated or new dependencies. '
- 'Please run "flutter update-packages --force-upgrade" to update them correctly '
- '(checksum ${pubspec.checksum.value} != $checksum).'
+ 'Please run "flutter update-packages --force-upgrade" to update them correctly.'
+ // DO NOT PRINT THE CHECKSUM HERE.
+ // It causes people to ignore the requirement to actually run the script.
);
needsUpdate = true;
} else {
@@ -331,11 +431,11 @@
required Set<String> specialDependencies,
required Map<String, PubspecDependency> explicitDependencies,
required Map<String, PubspecDependency> allDependencies,
- required bool doUpgrade,
+ required bool printPaths,
}) {
// Visit all the directories with pubspec.yamls we care about.
for (final Directory directory in packages) {
- if (doUpgrade) {
+ if (printPaths) {
globals.printTrace('Reading pubspec.yaml from: ${directory.path}');
}
final PubspecYaml pubspec = PubspecYaml(directory); // this parses the pubspec.yaml
@@ -404,12 +504,14 @@
}
}
- Future<void> _generateFakePackage({
+ Future<void> _pubGetAllDependencies({
required Directory tempDir,
required Iterable<PubspecDependency> dependencies,
required List<PubspecYaml> pubspecs,
required PubDependencyTree tree,
required bool doUpgrade,
+ required bool isolateEnvironment,
+ required bool reportDependenciesToTree,
}) async {
Directory? temporaryFlutterSdk;
final Directory syntheticPackageDir = tempDir.childDirectory('synthetic_package');
@@ -421,9 +523,10 @@
doUpgrade: doUpgrade,
),
);
- // Create a synthetic flutter SDK so that transitive flutter SDK
- // constraints are not affected by this upgrade.
- if (doUpgrade) {
+
+ if (isolateEnvironment) {
+ // Create a synthetic flutter SDK so that transitive flutter SDK
+ // constraints are not affected by this upgrade.
temporaryFlutterSdk = createTemporaryFlutterSdk(
globals.logger,
globals.fs,
@@ -433,8 +536,10 @@
);
}
- // Next we run "pub get" on it in order to force the download of any
+ // Run "pub get" on it in order to force the download of any
// needed packages to the pub cache, upgrading if requested.
+ // TODO(ianh): If this fails, the tool exits silently.
+ // It can fail, e.g., if --cherry-pick-version is invalid.
await pub.get(
context: PubContext.updatePackages,
project: FlutterProject.fromDirectory(syntheticPackageDir),
@@ -444,9 +549,9 @@
outputMode: PubOutputMode.none,
);
- if (doUpgrade) {
- // If upgrading, we run "pub deps --style=compact" on the result. We
- // pipe all the output to tree.fill(), which parses it so that it can
+ if (reportDependenciesToTree) {
+ // Run "pub deps --style=compact" on the result.
+ // We pipe all the output to tree.fill(), which parses it so that it can
// create a graph of all the dependencies so that we can figure out the
// transitive dependencies later. It also remembers which version was
// selected for each package.
@@ -459,40 +564,29 @@
}
}
- bool _upgradePubspecs({
+ void _processPubspecs({
required PubDependencyTree tree,
required List<PubspecYaml> pubspecs,
required Set<String> specialDependencies,
- required Map<String, PubspecDependency> explicitDependencies,
}) {
- // The transitive dependency tree for the fake package does not contain
- // dependencies between Flutter SDK packages and pub packages. We add them
- // here.
for (final PubspecYaml pubspec in pubspecs) {
final String package = pubspec.name;
specialDependencies.add(package);
tree._versions[package] = pubspec.version;
- assert(!tree._dependencyTree.containsKey(package));
- tree._dependencyTree[package] = <String>{};
for (final PubspecDependency dependency in pubspec.dependencies) {
if (dependency.kind == DependencyKind.normal) {
+ tree._dependencyTree[package] ??= <String>{};
tree._dependencyTree[package]!.add(dependency.name);
}
}
}
+ }
- if (boolArg('transitive-closure')) {
- tree._dependencyTree.forEach((String from, Set<String> to) {
- globals.printStatus('$from -> $to');
- });
- return true;
- }
-
- if (boolArg('paths')) {
- showDependencyPaths(from: stringArg('from')!, to: stringArg('to')!, tree: tree);
- return true;
- }
-
+ bool _updatePubspecs({
+ required PubDependencyTree tree,
+ required List<PubspecYaml> pubspecs,
+ required Set<String> specialDependencies,
+ }) {
// Now that we have collected all the data, we can apply our dependency
// versions to each pubspec.yaml that we collected. This mutates the
// pubspec.yaml files.
@@ -662,7 +756,6 @@
/// pubspec.yaml file.
const String kTransitiveMagicString= '# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"';
-
/// This is the string output before a checksum of the packages used.
const String kDependencyChecksum = '# PUBSPEC CHECKSUM: ';
@@ -1288,6 +1381,28 @@
static const String _sdkPrefix = ' sdk: ';
static const String _gitPrefix = ' git:';
+ PubspecDependency copyWith({
+ String? line,
+ String? name,
+ String? suffix,
+ bool? isTransitive,
+ DependencyKind? kind,
+ String? version,
+ String? sourcePath,
+ bool? isDevDependency,
+ }) {
+ return PubspecDependency(
+ line ?? this.line,
+ name ?? this.name,
+ suffix ?? this.suffix,
+ isTransitive: isTransitive ?? this.isTransitive,
+ kind: kind ?? this.kind,
+ version: version ?? this.version,
+ sourcePath: sourcePath ?? this.sourcePath,
+ isDevDependency: isDevDependency ?? this.isDevDependency,
+ );
+ }
+
/// Whether the dependency points to a package in the Flutter SDK.
///
/// There are two ways one can point to a Flutter package:
@@ -1353,16 +1468,16 @@
/// This generates the entry for this dependency for the pubspec.yaml for the
/// fake package that we'll use to get the version numbers figured out.
///
- /// When called with [doUpgrade] as [true], the version constrains will be set
- /// to >= whatever the previous version was. If [doUpgrade] is [false], then
+ /// When called with [allowUpgrade] as [true], the version constrains will be set
+ /// to >= whatever the previous version was. If [allowUpgrade] is [false], then
/// the previous version is used again as an exact pin.
- void describeForFakePubspec(StringBuffer dependencies, StringBuffer overrides, { bool doUpgrade = true }) {
+ void describeForFakePubspec(StringBuffer dependencies, StringBuffer overrides, { bool allowUpgrade = true }) {
final String versionToUse;
// This should only happen when manually adding new dependencies; otherwise
// versions should always be pinned exactly
if (version.isEmpty || version == 'any') {
versionToUse = 'any';
- } else if (doUpgrade) {
+ } else if (allowUpgrade) {
// Must wrap in quotes for Yaml parsing
versionToUse = "'>= $version'";
} else {
@@ -1445,7 +1560,7 @@
// Don't add pinned dependency if it is not in the set of all transitive dependencies.
if (!allTransitive.contains(package)) {
if (verbose) {
- globals.printStatus('Skipping $package because it was not transitive');
+ globals.printStatus(' - $package: $version (skipped because it was not a transitive dependency)');
}
return;
}
@@ -1457,7 +1572,7 @@
}
for (final PubspecDependency dependency in dependencies) {
if (!dependency.pointsToSdk) {
- dependency.describeForFakePubspec(result, overrides, doUpgrade: doUpgrade);
+ dependency.describeForFakePubspec(result, overrides, allowUpgrade: doUpgrade);
}
}
result.write(overrides.toString());
diff --git a/packages/flutter_tools/lib/src/commands/upgrade.dart b/packages/flutter_tools/lib/src/commands/upgrade.dart
index bc0d8ce..b7b54a1 100644
--- a/packages/flutter_tools/lib/src/commands/upgrade.dart
+++ b/packages/flutter_tools/lib/src/commands/upgrade.dart
@@ -80,7 +80,7 @@
gitTagVersion: GitTagVersion.determine(globals.processUtils, globals.platform),
flutterVersion: stringArg('working-directory') == null
? globals.flutterVersion
- : FlutterVersion(workingDirectory: _commandRunner.workingDirectory),
+ : FlutterVersion(flutterRoot: _commandRunner.workingDirectory!, fs: globals.fs),
verifyOnly: boolArg('verify-only'),
);
}
@@ -297,7 +297,11 @@
'for instructions.'
);
}
- return FlutterVersion(workingDirectory: workingDirectory, frameworkRevision: revision);
+ return FlutterVersion.fromRevision(
+ flutterRoot: workingDirectory!,
+ frameworkRevision: revision,
+ fs: globals.fs,
+ );
}
/// Attempts a hard reset to the given revision.
diff --git a/packages/flutter_tools/lib/src/context_runner.dart b/packages/flutter_tools/lib/src/context_runner.dart
index 1fae313..08cefe5 100644
--- a/packages/flutter_tools/lib/src/context_runner.dart
+++ b/packages/flutter_tools/lib/src/context_runner.dart
@@ -7,6 +7,7 @@
import 'dart:async';
import 'package:process/process.dart';
+import 'package:unified_analytics/unified_analytics.dart';
import 'android/android_builder.dart';
import 'android/android_sdk.dart';
@@ -87,6 +88,12 @@
body: runnerWrapper,
overrides: overrides,
fallbacks: <Type, Generator>{
+ Analytics: () => Analytics(
+ tool: DashTool.flutterTool,
+ flutterChannel: globals.flutterVersion.channel,
+ flutterVersion: globals.flutterVersion.frameworkVersion,
+ dartVersion: globals.flutterVersion.dartSdkVersion,
+ ),
AndroidBuilder: () => AndroidGradleBuilder(
java: globals.java,
logger: globals.logger,
@@ -226,7 +233,10 @@
config: globals.config,
platform: globals.platform,
),
- FlutterVersion: () => FlutterVersion(),
+ FlutterVersion: () => FlutterVersion(
+ fs: globals.fs,
+ flutterRoot: Cache.flutterRoot!,
+ ),
FuchsiaArtifacts: () => FuchsiaArtifacts.find(),
FuchsiaDeviceTools: () => FuchsiaDeviceTools(),
FuchsiaSdk: () => FuchsiaSdk(),
diff --git a/packages/flutter_tools/lib/src/dart/pub.dart b/packages/flutter_tools/lib/src/dart/pub.dart
index f9292c2..40e60f9 100644
--- a/packages/flutter_tools/lib/src/dart/pub.dart
+++ b/packages/flutter_tools/lib/src/dart/pub.dart
@@ -630,7 +630,7 @@
_logger.printStatus('''
Found an existing Pub cache at $pubCachePath.
It can be repaired by running `dart pub cache repair`.
-It can be reset by running `dart pub cache clear`.''');
+It can be reset by running `dart pub cache clean`.''');
}
}
final String? home = _platform.environment['HOME'];
diff --git a/packages/flutter_tools/lib/src/debug_adapters/README.md b/packages/flutter_tools/lib/src/debug_adapters/README.md
index 108ce14..096a49d 100644
--- a/packages/flutter_tools/lib/src/debug_adapters/README.md
+++ b/packages/flutter_tools/lib/src/debug_adapters/README.md
@@ -40,7 +40,10 @@
Arguments specific to `attachRequest` are:
-- `String? vmServiceUri` - the VM Service URI to attach to (if not supplied, Flutter will try to discover it from the device)
+- `String? vmServiceInfoFile` - the file to read the VM Service info from \*
+- `String? vmServiceUri` - the VM Service URI to attach to \*
+
+\* Only one of `vmServiceInfoFile` or `vmServiceUri` may be supplied. If neither are supplied, Flutter will try to discover it from the device.
## Custom Requests
diff --git a/packages/flutter_tools/lib/src/debug_adapters/flutter_adapter.dart b/packages/flutter_tools/lib/src/debug_adapters/flutter_adapter.dart
index 4bf3670..e0e3402 100644
--- a/packages/flutter_tools/lib/src/debug_adapters/flutter_adapter.dart
+++ b/packages/flutter_tools/lib/src/debug_adapters/flutter_adapter.dart
@@ -11,11 +11,12 @@
import '../base/io.dart';
import '../cache.dart';
import '../convert.dart';
+import '../globals.dart' as globals show fs;
import 'flutter_adapter_args.dart';
import 'flutter_base_adapter.dart';
/// A DAP Debug Adapter for running and debugging Flutter applications.
-class FlutterDebugAdapter extends FlutterBaseDebugAdapter {
+class FlutterDebugAdapter extends FlutterBaseDebugAdapter with VmServiceInfoFileUtils {
FlutterDebugAdapter(
super.channel, {
required super.fileSystem,
@@ -120,6 +121,16 @@
@override
Future<void> attachImpl() async {
final FlutterAttachRequestArguments args = this.args as FlutterAttachRequestArguments;
+ String? vmServiceUri = args.vmServiceUri;
+ final String? vmServiceInfoFile = args.vmServiceInfoFile;
+
+ if (vmServiceUri != null && vmServiceInfoFile != null) {
+ sendConsoleOutput(
+ 'To attach, provide only one (or neither) of vmServiceUri/vmServiceInfoFile',
+ );
+ handleSessionTerminate();
+ return;
+ }
launchProgress = startProgressNotification(
'launch',
@@ -127,7 +138,11 @@
message: 'Attaching…',
);
- final String? vmServiceUri = args.vmServiceUri;
+ if (vmServiceUri == null && vmServiceInfoFile != null) {
+ final Uri uriFromFile = await waitForVmServiceInfoFile(logger, globals.fs.file(vmServiceInfoFile));
+ vmServiceUri = uriFromFile.toString();
+ }
+
final List<String> toolArgs = <String>[
'attach',
'--machine',
@@ -170,6 +185,8 @@
switch (request.command) {
case 'hotRestart':
case 'hotReload':
+ // This convention is for the internal IDE client.
+ case r'$/hotReload':
final bool isFullRestart = request.command == 'hotRestart';
await _performRestart(isFullRestart, args?.args['reason'] as String?);
sendResponse(null);
diff --git a/packages/flutter_tools/lib/src/debug_adapters/flutter_adapter_args.dart b/packages/flutter_tools/lib/src/debug_adapters/flutter_adapter_args.dart
index 55d1666..8e90a6e 100644
--- a/packages/flutter_tools/lib/src/debug_adapters/flutter_adapter_args.dart
+++ b/packages/flutter_tools/lib/src/debug_adapters/flutter_adapter_args.dart
@@ -17,6 +17,7 @@
this.customTool,
this.customToolReplacesArgs,
this.vmServiceUri,
+ this.vmServiceInfoFile,
this.program,
super.restart,
super.name,
@@ -36,6 +37,7 @@
customTool = obj['customTool'] as String?,
customToolReplacesArgs = obj['customToolReplacesArgs'] as int?,
vmServiceUri = obj['vmServiceUri'] as String?,
+ vmServiceInfoFile = obj['vmServiceInfoFile'] as String?,
program = obj['program'] as String?,
super.fromMap();
@@ -64,8 +66,15 @@
final int? customToolReplacesArgs;
/// The VM Service URI of the running Flutter app to connect to.
+ ///
+ /// Only one of this or [vmServiceInfoFile] (or neither) can be supplied.
final String? vmServiceUri;
+ /// The VM Service info file to extract the VM Service URI from to attach to.
+ ///
+ /// Only one of this or [vmServiceUri] (or neither) can be supplied.
+ final String? vmServiceInfoFile;
+
/// The program/Flutter app to be run.
final String? program;
diff --git a/packages/flutter_tools/lib/src/doctor.dart b/packages/flutter_tools/lib/src/doctor.dart
index 3978d0d..eb975fc 100644
--- a/packages/flutter_tools/lib/src/doctor.dart
+++ b/packages/flutter_tools/lib/src/doctor.dart
@@ -123,7 +123,7 @@
FlutterValidator(
fileSystem: globals.fs,
platform: globals.platform,
- flutterVersion: () => globals.flutterVersion,
+ flutterVersion: () => globals.flutterVersion.fetchTagsAndGetVersion(clock: globals.systemClock),
devToolsVersion: () => globals.cache.devToolsVersion,
processManager: globals.processManager,
userMessages: userMessages,
diff --git a/packages/flutter_tools/lib/src/globals.dart b/packages/flutter_tools/lib/src/globals.dart
index 0f23939..59045aa 100644
--- a/packages/flutter_tools/lib/src/globals.dart
+++ b/packages/flutter_tools/lib/src/globals.dart
@@ -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 'package:intl/date_symbol_data_local.dart';
import 'package:process/process.dart';
import 'package:unified_analytics/unified_analytics.dart';
@@ -91,19 +90,7 @@
// Analytics instance for package:unified_analytics for telemetry
// reporting for all Flutter and Dart related tooling
-Analytics get analytics => context.get<Analytics>() ?? getDefaultAnalytics();
-Analytics getDefaultAnalytics() {
-
- initializeDateFormatting();
- final Analytics defaultAnalytics = Analytics(
- tool: DashTool.flutterTool,
- flutterChannel: flutterVersion.channel,
- flutterVersion: flutterVersion.frameworkVersion,
- dartVersion: flutterVersion.dartSdkVersion,
- );
-
- return defaultAnalytics;
-}
+Analytics get analytics => context.get<Analytics>()!;
/// Currently active implementation of the file system.
///
diff --git a/packages/flutter_tools/lib/src/intellij/intellij_validator.dart b/packages/flutter_tools/lib/src/intellij/intellij_validator.dart
index 7f09515..691d8e5 100644
--- a/packages/flutter_tools/lib/src/intellij/intellij_validator.dart
+++ b/packages/flutter_tools/lib/src/intellij/intellij_validator.dart
@@ -376,6 +376,7 @@
'IntelliJ IDEA.app': _ultimateEditionId,
'IntelliJ IDEA Ultimate.app': _ultimateEditionId,
'IntelliJ IDEA CE.app': _communityEditionId,
+ 'IntelliJ IDEA Community Edition.app': _communityEditionId,
};
static Iterable<DoctorValidator> installed({
@@ -482,6 +483,17 @@
]),
));
}
+
+ // Remove JetBrains Toolbox link apps. These tiny apps just
+ // link to the full app, will get detected elsewhere in our search.
+ validators.removeWhere((DoctorValidator validator) {
+ final String identifierKey = plistParser.getValueFromFile(
+ (validator as IntelliJValidatorOnMac).plistFile,
+ PlistParser.kCFBundleIdentifierKey,
+ ) as String;
+ return identifierKey.contains('com.jetbrains.toolbox.linkapp');
+ });
+
return validators;
}
diff --git a/packages/flutter_tools/lib/src/ios/devices.dart b/packages/flutter_tools/lib/src/ios/devices.dart
index ceebcb6..000529d 100644
--- a/packages/flutter_tools/lib/src/ios/devices.dart
+++ b/packages/flutter_tools/lib/src/ios/devices.dart
@@ -16,6 +16,7 @@
import '../base/os.dart';
import '../base/platform.dart';
import '../base/utils.dart';
+import '../base/version.dart';
import '../build_info.dart';
import '../convert.dart';
import '../device.dart';
@@ -295,10 +296,13 @@
final IMobileDevice _iMobileDevice;
final IProxy _iproxy;
+ Version? get sdkVersion {
+ return Version.parse(_sdkVersion);
+ }
+
/// May be 0 if version cannot be parsed.
int get majorSdkVersion {
- final String? majorVersionString = _sdkVersion?.split('.').first.trim();
- return majorVersionString != null ? int.tryParse(majorVersionString) ?? 0 : 0;
+ return sdkVersion?.major ?? 0;
}
@override
diff --git a/packages/flutter_tools/lib/src/ios/ios_deploy.dart b/packages/flutter_tools/lib/src/ios/ios_deploy.dart
index 2d1f7d6..846b9b4 100644
--- a/packages/flutter_tools/lib/src/ios/ios_deploy.dart
+++ b/packages/flutter_tools/lib/src/ios/ios_deploy.dart
@@ -338,6 +338,8 @@
RegExp lldbRun = RegExp(r'\(lldb\)\s*run');
final Completer<bool> debuggerCompleter = Completer<bool>();
+
+ bool receivedLogs = false;
try {
_iosDeployProcess = await _processUtils.start(
_launchCommand,
@@ -386,8 +388,6 @@
if (lldbRun.hasMatch(line)) {
_logger.printTrace(line);
_debuggerState = _IOSDeployDebuggerState.launching;
- // TODO(vashworth): Remove all debugger state comments when https://github.com/flutter/flutter/issues/126412 is resolved.
- _logger.printTrace('Debugger state set to launching.');
return;
}
// Next line after "run" must be "success", or the attach failed.
@@ -396,7 +396,6 @@
_logger.printTrace(line);
final bool attachSuccess = line == 'success';
_debuggerState = attachSuccess ? _IOSDeployDebuggerState.attached : _IOSDeployDebuggerState.detached;
- _logger.printTrace('Debugger state set to ${attachSuccess ? 'attached' : 'detached'}.');
if (!debuggerCompleter.isCompleted) {
debuggerCompleter.complete(attachSuccess);
}
@@ -425,7 +424,6 @@
// Even though we're not "detached", just stopped, mark as detached so the backtrace
// is only show in verbose.
_debuggerState = _IOSDeployDebuggerState.detached;
- _logger.printTrace('Debugger state set to detached.');
// If we paused the app and are waiting to resume it, complete the completer
final Completer<void>? processResumeCompleter = _processResumeCompleter;
@@ -465,7 +463,6 @@
_logger.printTrace(line);
// we marked this detached when we received [_backTraceAll]
_debuggerState = _IOSDeployDebuggerState.attached;
- _logger.printTrace('Debugger state set to attached.');
return;
}
@@ -480,6 +477,16 @@
// This will still cause "legit" logged newlines to be doubled...
} else if (!_debuggerOutput.isClosed) {
_debuggerOutput.add(line);
+
+ // Sometimes the `ios-deploy` process does not return logs from the
+ // application after attaching, such as the Dart VM url. In CI,
+ // `idevicesyslog` is used as a fallback to get logs. Print a
+ // message to indicate whether logs were received from `ios-deploy`
+ // to help with debugging.
+ if (!receivedLogs) {
+ _logger.printTrace('Received logs from ios-deploy.');
+ receivedLogs = true;
+ }
}
lastLineFromDebugger = line;
});
diff --git a/packages/flutter_tools/lib/src/ios/mac.dart b/packages/flutter_tools/lib/src/ios/mac.dart
index cbd1f89..86a4a05 100644
--- a/packages/flutter_tools/lib/src/ios/mac.dart
+++ b/packages/flutter_tools/lib/src/ios/mac.dart
@@ -357,10 +357,10 @@
buildCommands.add('SCRIPT_OUTPUT_STREAM_FILE=${scriptOutputPipeFile.absolute.path}');
}
- final File resultBundleFile = tempDir.childFile(_kResultBundlePath);
+ final Directory resultBundleDirectory = tempDir.childDirectory(_kResultBundlePath);
buildCommands.addAll(<String>[
'-resultBundlePath',
- resultBundleFile.absolute.path,
+ resultBundleDirectory.absolute.path,
'-resultBundleVersion',
_kResultBundleVersion,
]);
@@ -382,7 +382,7 @@
final Stopwatch sw = Stopwatch()..start();
initialBuildStatus = globals.logger.startProgress('Running Xcode build...');
- buildResult = await _runBuildWithRetries(buildCommands, app, resultBundleFile);
+ buildResult = await _runBuildWithRetries(buildCommands, app, resultBundleDirectory);
// Notifies listener that no more output is coming.
scriptOutputPipeFile?.writeAsStringSync('all done');
@@ -512,14 +512,14 @@
}
}
-Future<RunResult?> _runBuildWithRetries(List<String> buildCommands, BuildableIOSApp app, File resultBundleFile) async {
+Future<RunResult?> _runBuildWithRetries(List<String> buildCommands, BuildableIOSApp app, Directory resultBundleDirectory) async {
int buildRetryDelaySeconds = 1;
int remainingTries = 8;
RunResult? buildResult;
while (remainingTries > 0) {
- if (resultBundleFile.existsSync()) {
- resultBundleFile.deleteSync(recursive: true);
+ if (resultBundleDirectory.existsSync()) {
+ resultBundleDirectory.deleteSync(recursive: true);
}
remainingTries--;
buildRetryDelaySeconds *= 2;
diff --git a/packages/flutter_tools/lib/src/isolated/devfs_web.dart b/packages/flutter_tools/lib/src/isolated/devfs_web.dart
index f4d4f70..903eae9 100644
--- a/packages/flutter_tools/lib/src/isolated/devfs_web.dart
+++ b/packages/flutter_tools/lib/src/isolated/devfs_web.dart
@@ -493,7 +493,7 @@
/// Write a single file into the in-memory cache.
void writeFile(String filePath, String contents) {
- writeBytes(filePath, utf8.encode(contents) as Uint8List);
+ writeBytes(filePath, const Utf8Encoder().convert(contents));
}
void writeBytes(String filePath, Uint8List contents) {
diff --git a/packages/flutter_tools/lib/src/license_collector.dart b/packages/flutter_tools/lib/src/license_collector.dart
index 041467b..289962a 100644
--- a/packages/flutter_tools/lib/src/license_collector.dart
+++ b/packages/flutter_tools/lib/src/license_collector.dart
@@ -82,11 +82,10 @@
}
}
- final List<String> combinedLicensesList = packageLicenses.keys
- .map<String>((String license) {
- final List<String> packageNames = packageLicenses[license]!.toList()
- ..sort();
- return '${packageNames.join('\n')}\n\n$license';
+ final List<String> combinedLicensesList = packageLicenses.entries
+ .map<String>((MapEntry<String, Set<String>> entry) {
+ final List<String> packageNames = entry.value.toList()..sort();
+ return '${packageNames.join('\n')}\n\n${entry.key}';
}).toList();
combinedLicensesList.sort();
diff --git a/packages/flutter_tools/lib/src/localizations/gen_l10n.dart b/packages/flutter_tools/lib/src/localizations/gen_l10n.dart
index 01f97aa..4288d5f 100644
--- a/packages/flutter_tools/lib/src/localizations/gen_l10n.dart
+++ b/packages/flutter_tools/lib/src/localizations/gen_l10n.dart
@@ -47,6 +47,9 @@
precacheLanguageAndRegionTags();
+ // Use \r\n if project's pubspec file contains \r\n.
+ final bool useCRLF = fileSystem.file('pubspec.yaml').readAsStringSync().contains('\r\n');
+
LocalizationsGenerator generator;
try {
generator = LocalizationsGenerator(
@@ -71,7 +74,7 @@
suppressWarnings: options.suppressWarnings,
)
..loadResources()
- ..writeOutputFiles(isFromYaml: true);
+ ..writeOutputFiles(isFromYaml: true, useCRLF: useCRLF);
} on L10nException catch (e) {
throwToolExit(e.message);
}
@@ -79,7 +82,6 @@
final List<String> outputFileList = generator.outputFileList;
final File? untranslatedMessagesFile = generator.untranslatedMessagesFile;
- // All other post processing.
if (options.format) {
final List<String> formatFileList = outputFileList.toList();
if (untranslatedMessagesFile != null) {
@@ -1157,6 +1159,7 @@
// When traversing through a placeholderExpr node, return "$placeholderName".
// When traversing through a pluralExpr node, return "$tempVarN" and add variable declaration in "tempVariables".
// When traversing through a selectExpr node, return "$tempVarN" and add variable declaration in "tempVariables".
+ // When traversing through an argumentExpr node, return "$tempVarN" and add variable declaration in "tempVariables".
// When traversing through a message node, return concatenation of all of "generateVariables(child)" for each child.
String generateVariables(Node node, { bool isRoot = false }) {
switch (node.type) {
@@ -1259,6 +1262,34 @@
.replaceAll('@(selectCases)', selectLogicArgs.join('\n'))
);
return '\$$tempVarName';
+ case ST.argumentExpr:
+ requiresIntlImport = true;
+ assert(node.children[1].type == ST.identifier);
+ assert(node.children[3].type == ST.argType);
+ assert(node.children[7].type == ST.identifier);
+ final String identifierName = node.children[1].value!;
+ final Node formatType = node.children[7];
+ // Check that formatType is a valid intl.DateFormat.
+ if (!validDateFormats.contains(formatType.value)) {
+ throw L10nParserException(
+ 'Date format "${formatType.value!}" for placeholder '
+ '$identifierName does not have a corresponding DateFormat '
+ "constructor\n. Check the intl library's DateFormat class "
+ 'constructors for allowed date formats, or set "isCustomDateFormat" attribute '
+ 'to "true".',
+ _inputFileNames[locale]!,
+ message.resourceId,
+ translationForMessage,
+ formatType.positionInMessage,
+ );
+ }
+ final String tempVarName = getTempVariableName();
+ tempVariables.add(dateVariableTemplate
+ .replaceAll('@(varName)', tempVarName)
+ .replaceAll('@(formatType)', formatType.value!)
+ .replaceAll('@(argument)', identifierName)
+ );
+ return '\$$tempVarName';
// ignore: no_default_cases
default:
throw Exception('Cannot call "generateHelperMethod" on node type ${node.type}');
@@ -1281,7 +1312,7 @@
}
}
- List<String> writeOutputFiles({ bool isFromYaml = false }) {
+ List<String> writeOutputFiles({ bool isFromYaml = false, bool useCRLF = false }) {
// First, generate the string contents of all necessary files.
final String generatedLocalizationsFile = _generateCode();
@@ -1299,7 +1330,9 @@
syntheticPackageDirectory.createSync(recursive: true);
final File flutterGenPubspec = syntheticPackageDirectory.childFile('pubspec.yaml');
if (!flutterGenPubspec.existsSync()) {
- flutterGenPubspec.writeAsStringSync(emptyPubspecTemplate);
+ flutterGenPubspec.writeAsStringSync(
+ useCRLF ? emptyPubspecTemplate.replaceAll('\n', '\r\n') : emptyPubspecTemplate
+ );
}
}
@@ -1318,11 +1351,13 @@
// Generate the required files for localizations.
_languageFileMap.forEach((File file, String contents) {
- file.writeAsStringSync(contents);
+ file.writeAsStringSync(useCRLF ? contents.replaceAll('\n', '\r\n') : contents);
_outputFileList.add(file.absolute.path);
});
- baseOutputFile.writeAsStringSync(generatedLocalizationsFile);
+ baseOutputFile.writeAsStringSync(
+ useCRLF ? generatedLocalizationsFile.replaceAll('\n', '\r\n') : generatedLocalizationsFile
+ );
final File? messagesFile = untranslatedMessagesFile;
if (messagesFile != null) {
_generateUntranslatedMessagesFile(logger, messagesFile);
@@ -1358,12 +1393,12 @@
if (!inputsAndOutputsListFileLocal.existsSync()) {
inputsAndOutputsListFileLocal.createSync(recursive: true);
}
-
+ final String filesListContent = json.encode(<String, Object> {
+ 'inputs': _inputFileList,
+ 'outputs': _outputFileList,
+ });
inputsAndOutputsListFileLocal.writeAsStringSync(
- json.encode(<String, Object> {
- 'inputs': _inputFileList,
- 'outputs': _outputFileList,
- }),
+ useCRLF ? filesListContent.replaceAll('\n', '\r\n') : filesListContent,
);
}
diff --git a/packages/flutter_tools/lib/src/localizations/gen_l10n_templates.dart b/packages/flutter_tools/lib/src/localizations/gen_l10n_templates.dart
index 022e496..15e9cd6 100644
--- a/packages/flutter_tools/lib/src/localizations/gen_l10n_templates.dart
+++ b/packages/flutter_tools/lib/src/localizations/gen_l10n_templates.dart
@@ -157,6 +157,9 @@
},
);''';
+const String dateVariableTemplate = '''
+ String @(varName) = intl.DateFormat.@(formatType)(localeName).format(@(argument));''';
+
const String classFileTemplate = '''
@(header)@(requiresIntlImport)import '@(fileName)';
diff --git a/packages/flutter_tools/lib/src/localizations/gen_l10n_types.dart b/packages/flutter_tools/lib/src/localizations/gen_l10n_types.dart
index 7aad6d9..a978e43 100644
--- a/packages/flutter_tools/lib/src/localizations/gen_l10n_types.dart
+++ b/packages/flutter_tools/lib/src/localizations/gen_l10n_types.dart
@@ -27,7 +27,7 @@
// * <https://pub.dev/packages/intl>
// * <https://pub.dev/documentation/intl/latest/intl/DateFormat-class.html>
// * <https://api.dartlang.org/stable/2.7.0/dart-core/DateTime-class.html>
-const Set<String> _validDateFormats = <String>{
+const Set<String> validDateFormats = <String>{
'd',
'E',
'EEEE',
@@ -244,13 +244,14 @@
String? type;
bool isPlural = false;
bool isSelect = false;
+ bool isDateTime = false;
+ bool requiresDateFormatting = false;
bool get requiresFormatting => requiresDateFormatting || requiresNumFormatting;
- bool get requiresDateFormatting => type == 'DateTime';
bool get requiresNumFormatting => <String>['int', 'num', 'double'].contains(type) && format != null;
bool get hasValidNumberFormat => _validNumberFormats.contains(format);
bool get hasNumberFormatWithParameters => _numberFormatsWithNamedParameters.contains(format);
- bool get hasValidDateFormat => _validDateFormats.contains(format);
+ bool get hasValidDateFormat => validDateFormats.contains(format);
static String? _stringAttribute(
String resourceId,
@@ -488,7 +489,12 @@
final List<Node> traversalStack = <Node>[parsedMessages[locale]!];
while (traversalStack.isNotEmpty) {
final Node node = traversalStack.removeLast();
- if (<ST>[ST.placeholderExpr, ST.pluralExpr, ST.selectExpr].contains(node.type)) {
+ if (<ST>[
+ ST.placeholderExpr,
+ ST.pluralExpr,
+ ST.selectExpr,
+ ST.argumentExpr
+ ].contains(node.type)) {
final String identifier = node.children[1].value!;
Placeholder? placeholder = getPlaceholder(identifier);
if (placeholder == null) {
@@ -499,6 +505,14 @@
placeholder.isPlural = true;
} else if (node.type == ST.selectExpr) {
placeholder.isSelect = true;
+ } else if (node.type == ST.argumentExpr) {
+ placeholder.isDateTime = true;
+ } else {
+ // Here the node type must be ST.placeholderExpr.
+ // A DateTime placeholder must require date formatting.
+ if (placeholder.type == 'DateTime') {
+ placeholder.requiresDateFormatting = true;
+ }
}
}
traversalStack.addAll(node.children);
@@ -510,9 +524,16 @@
..sort((MapEntry<String, Placeholder> p1, MapEntry<String, Placeholder> p2) => p1.key.compareTo(p2.key))
);
+ bool atMostOneOf(bool x, bool y, bool z) {
+ return x && !y && !z
+ || !x && y && !z
+ || !x && !y && z
+ || !x && !y && !z;
+ }
+
for (final Placeholder placeholder in placeholders.values) {
- if (placeholder.isPlural && placeholder.isSelect) {
- throw L10nException('Placeholder is used as both a plural and select in certain languages.');
+ if (!atMostOneOf(placeholder.isPlural, placeholder.isDateTime, placeholder.isSelect)) {
+ throw L10nException('Placeholder is used as plural/select/datetime in certain languages.');
} else if (placeholder.isPlural) {
if (placeholder.type == null) {
placeholder.type = 'num';
@@ -526,6 +547,12 @@
} else if (placeholder.type != 'String') {
throw L10nException("Placeholders used in selects must be of type 'String'");
}
+ } else if (placeholder.isDateTime) {
+ if (placeholder.type == null) {
+ placeholder.type = 'DateTime';
+ } else if (placeholder.type != 'DateTime') {
+ throw L10nException("Placeholders used in datetime expressions much be of type 'DateTime'");
+ }
}
placeholder.type ??= 'Object';
}
diff --git a/packages/flutter_tools/lib/src/localizations/message_parser.dart b/packages/flutter_tools/lib/src/localizations/message_parser.dart
index dc05744..49a04ff 100644
--- a/packages/flutter_tools/lib/src/localizations/message_parser.dart
+++ b/packages/flutter_tools/lib/src/localizations/message_parser.dart
@@ -22,11 +22,16 @@
number,
identifier,
empty,
+ colon,
+ date,
+ time,
// Nonterminal Types
message,
placeholderExpr,
+ argumentExpr,
+
pluralExpr,
pluralParts,
pluralPart,
@@ -34,6 +39,8 @@
selectExpr,
selectParts,
selectPart,
+
+ argType,
}
// The grammar of the syntax.
@@ -43,6 +50,7 @@
<ST>[ST.placeholderExpr, ST.message],
<ST>[ST.pluralExpr, ST.message],
<ST>[ST.selectExpr, ST.message],
+ <ST>[ST.argumentExpr, ST.message],
<ST>[ST.empty],
],
ST.placeholderExpr: <List<ST>>[
@@ -73,6 +81,13 @@
<ST>[ST.number, ST.openBrace, ST.message, ST.closeBrace],
<ST>[ST.other, ST.openBrace, ST.message, ST.closeBrace],
],
+ ST.argumentExpr: <List<ST>>[
+ <ST>[ST.openBrace, ST.identifier, ST.comma, ST.argType, ST.comma, ST.colon, ST.colon, ST.identifier, ST.closeBrace],
+ ],
+ ST.argType: <List<ST>>[
+ <ST>[ST.date],
+ <ST>[ST.time],
+ ],
};
class Node {
@@ -100,6 +115,8 @@
Node.selectKeyword(this.positionInMessage): type = ST.select, value = 'select';
Node.otherKeyword(this.positionInMessage): type = ST.other, value = 'other';
Node.empty(this.positionInMessage): type = ST.empty, value = '';
+ Node.dateKeyword(this.positionInMessage): type = ST.date, value = 'date';
+ Node.timeKeyword(this.positionInMessage): type = ST.time, value = 'time';
String? value;
late ST type;
@@ -162,6 +179,7 @@
RegExp alphanumeric = RegExp(r'[a-zA-Z0-9|_]+');
RegExp comma = RegExp(r',');
RegExp equalSign = RegExp(r'=');
+RegExp colon = RegExp(r':');
// List of token matchers ordered by precedence
Map<ST, RegExp> matchers = <ST, RegExp>{
@@ -169,6 +187,7 @@
ST.number: numeric,
ST.comma: comma,
ST.equalSign: equalSign,
+ ST.colon: colon,
ST.identifier: alphanumeric,
};
@@ -312,6 +331,10 @@
matchedType = ST.select;
case 'other':
matchedType = ST.other;
+ case 'date':
+ matchedType = ST.date;
+ case 'time':
+ matchedType = ST.time;
}
tokens.add(Node(matchedType!, startIndex, value: match.group(0)));
startIndex = match.end;
@@ -354,9 +377,9 @@
switch (symbol) {
case ST.message:
if (tokens.isEmpty) {
- parseAndConstructNode(ST.message, 4);
+ parseAndConstructNode(ST.message, 5);
} else if (tokens[0].type == ST.closeBrace) {
- parseAndConstructNode(ST.message, 4);
+ parseAndConstructNode(ST.message, 5);
} else if (tokens[0].type == ST.string) {
parseAndConstructNode(ST.message, 0);
} else if (tokens[0].type == ST.openBrace) {
@@ -364,6 +387,8 @@
parseAndConstructNode(ST.message, 2);
} else if (3 < tokens.length && tokens[3].type == ST.select) {
parseAndConstructNode(ST.message, 3);
+ } else if (3 < tokens.length && (tokens[3].type == ST.date || tokens[3].type == ST.time)) {
+ parseAndConstructNode(ST.message, 4);
} else {
parseAndConstructNode(ST.message, 1);
}
@@ -373,6 +398,16 @@
}
case ST.placeholderExpr:
parseAndConstructNode(ST.placeholderExpr, 0);
+ case ST.argumentExpr:
+ parseAndConstructNode(ST.argumentExpr, 0);
+ case ST.argType:
+ if (tokens.isNotEmpty && tokens[0].type == ST.date) {
+ parseAndConstructNode(ST.argType, 0);
+ } else if (tokens.isNotEmpty && tokens[0].type == ST.time) {
+ parseAndConstructNode(ST.argType, 1);
+ } else {
+ throw L10nException('ICU Syntax Error. Found unknown argument type.');
+ }
case ST.pluralExpr:
parseAndConstructNode(ST.pluralExpr, 0);
case ST.pluralParts:
diff --git a/packages/flutter_tools/lib/src/macos/application_package.dart b/packages/flutter_tools/lib/src/macos/application_package.dart
index b2b9934..036de96 100644
--- a/packages/flutter_tools/lib/src/macos/application_package.dart
+++ b/packages/flutter_tools/lib/src/macos/application_package.dart
@@ -173,7 +173,7 @@
String bundleDirectory(BuildInfo buildInfo) {
return sentenceCase(buildInfo.mode.cliName) + (buildInfo.flavor != null
- ? ' ${sentenceCase(buildInfo.flavor!)}'
+ ? '-${buildInfo.flavor!}'
: '');
}
diff --git a/packages/flutter_tools/lib/src/macos/xcdevice.dart b/packages/flutter_tools/lib/src/macos/xcdevice.dart
index 1af4c76..c53fdca 100644
--- a/packages/flutter_tools/lib/src/macos/xcdevice.dart
+++ b/packages/flutter_tools/lib/src/macos/xcdevice.dart
@@ -12,6 +12,7 @@
import '../base/logger.dart';
import '../base/platform.dart';
import '../base/process.dart';
+import '../base/version.dart';
import '../build_info.dart';
import '../cache.dart';
import '../convert.dart';
@@ -493,7 +494,7 @@
// },
// ...
- final List<IOSDevice> devices = <IOSDevice>[];
+ final Map<String, IOSDevice> deviceMap = <String, IOSDevice>{};
for (final Object device in allAvailableDevices) {
if (device is Map<String, Object?>) {
// Only include iPhone, iPad, iPod, or other iOS devices.
@@ -531,33 +532,57 @@
}
}
- String? sdkVersion = _sdkVersion(device);
+ String? sdkVersionString = _sdkVersion(device);
- if (sdkVersion != null) {
+ if (sdkVersionString != null) {
final String? buildVersion = _buildVersion(device);
if (buildVersion != null) {
- sdkVersion = '$sdkVersion $buildVersion';
+ sdkVersionString = '$sdkVersionString $buildVersion';
}
}
- devices.add(IOSDevice(
+ // Duplicate entries started appearing in Xcode 15, possibly due to
+ // Xcode's new device connectivity stack.
+ // If a duplicate entry is found in `xcdevice list`, don't overwrite
+ // existing entry when the existing entry indicates the device is
+ // connected and the current entry indicates the device is not connected.
+ // Don't overwrite if current entry's sdkVersion is null.
+ // Don't overwrite if both entries indicate the device is not
+ // connected and the existing entry has a higher sdkVersion.
+ if (deviceMap.containsKey(identifier)) {
+ final IOSDevice deviceInMap = deviceMap[identifier]!;
+ if ((deviceInMap.isConnected && !isConnected) || sdkVersionString == null) {
+ continue;
+ }
+
+ final Version? sdkVersion = Version.parse(sdkVersionString);
+ if (!deviceInMap.isConnected &&
+ !isConnected &&
+ sdkVersion != null &&
+ deviceInMap.sdkVersion != null &&
+ deviceInMap.sdkVersion!.compareTo(sdkVersion) > 0) {
+ continue;
+ }
+ }
+
+ deviceMap[identifier] = IOSDevice(
identifier,
name: name,
cpuArchitecture: _cpuArchitecture(device),
connectionInterface: _interfaceType(device),
isConnected: isConnected,
- sdkVersion: sdkVersion,
+ sdkVersion: sdkVersionString,
iProxy: _iProxy,
fileSystem: globals.fs,
logger: _logger,
iosDeploy: _iosDeploy,
iMobileDevice: _iMobileDevice,
platform: globals.platform,
- devModeEnabled: devModeEnabled
- ));
+ devModeEnabled: devModeEnabled,
+ );
}
}
- return devices;
+ return deviceMap.values.toList();
}
/// Despite the name, com.apple.platform.iphoneos includes iPhone, iPads, and all iOS devices.
diff --git a/packages/flutter_tools/lib/src/project_validator.dart b/packages/flutter_tools/lib/src/project_validator.dart
index 791642a..57c3f8d 100644
--- a/packages/flutter_tools/lib/src/project_validator.dart
+++ b/packages/flutter_tools/lib/src/project_validator.dart
@@ -136,7 +136,10 @@
));
// FlutterVersion
- final FlutterVersion version = FlutterVersion(workingDirectory: project.directory.absolute.path);
+ final FlutterVersion version = FlutterVersion(
+ flutterRoot: Cache.flutterRoot!,
+ fs: fileSystem,
+ );
result.add(ProjectValidatorResult(
name: 'FlutterVersion.frameworkRevision',
value: _toJsonValue(version.frameworkRevision),
diff --git a/packages/flutter_tools/lib/src/protocol_discovery.dart b/packages/flutter_tools/lib/src/protocol_discovery.dart
index d21e602..578052b 100644
--- a/packages/flutter_tools/lib/src/protocol_discovery.dart
+++ b/packages/flutter_tools/lib/src/protocol_discovery.dart
@@ -167,7 +167,6 @@
final StreamController<T> streamControllerInstance = StreamController<T>.broadcast();
streamControllerInstance.onListen = () {
for (final dynamic event in _events) {
- assert(T is! List);
if (event is T) {
streamControllerInstance.add(event);
} else {
diff --git a/packages/flutter_tools/lib/src/resident_devtools_handler.dart b/packages/flutter_tools/lib/src/resident_devtools_handler.dart
index 2dc0aae..3b75214 100644
--- a/packages/flutter_tools/lib/src/resident_devtools_handler.dart
+++ b/packages/flutter_tools/lib/src/resident_devtools_handler.dart
@@ -35,6 +35,7 @@
Future<void> serveAndAnnounceDevTools({
Uri? devToolsServerAddress,
required List<FlutterDevice?> flutterDevices,
+ bool isStartPaused = false,
});
bool launchDevToolsInBrowser({required List<FlutterDevice?> flutterDevices});
@@ -71,6 +72,7 @@
Future<void> serveAndAnnounceDevTools({
Uri? devToolsServerAddress,
required List<FlutterDevice?> flutterDevices,
+ bool isStartPaused = false,
}) async {
assert(!_readyToAnnounce);
if (!_residentRunner.supportsServiceProtocol || _devToolsLauncher == null) {
@@ -88,20 +90,10 @@
assert(!_readyToAnnounce);
return;
}
- final List<FlutterDevice?> devicesWithExtension = await _devicesWithExtensions(flutterDevices);
- await _maybeCallDevToolsUriServiceExtension(devicesWithExtension);
- await _callConnectedVmServiceUriExtension(devicesWithExtension);
-
- if (_shutdown) {
- // If we're shutting down, no point reporting the debugger list.
- return;
- }
- _readyToAnnounce = true;
- assert(_devToolsLauncher!.activeDevToolsServer != null);
final Uri? devToolsUrl = _devToolsLauncher!.devToolsUrl;
if (devToolsUrl != null) {
- for (final FlutterDevice? device in devicesWithExtension) {
+ for (final FlutterDevice? device in flutterDevices) {
if (device == null) {
continue;
}
@@ -111,11 +103,43 @@
}
}
+ Future<void> callServiceExtensions() async {
+ final List<FlutterDevice?> devicesWithExtension = await _devicesWithExtensions(flutterDevices);
+ await Future.wait(
+ <Future<void>>[
+ _maybeCallDevToolsUriServiceExtension(devicesWithExtension),
+ _callConnectedVmServiceUriExtension(devicesWithExtension)
+ ]
+ );
+ }
+
+ // If the application is starting paused, we can't invoke service extensions
+ // as they're handled on the target app's paused isolate. Since invoking
+ // service extensions will block in this situation, we should wait to invoke
+ // them until after we've output the DevTools connection details.
+ if (!isStartPaused) {
+ await callServiceExtensions();
+ }
+
+ // This check needs to happen after the possible asynchronous call above,
+ // otherwise a shutdown event might be missed and the DevTools launcher may
+ // no longer be initialized.
+ if (_shutdown) {
+ // If we're shutting down, no point reporting the debugger list.
+ return;
+ }
+
+ _readyToAnnounce = true;
+ assert(_devToolsLauncher!.activeDevToolsServer != null);
if (_residentRunner.reportedDebuggers) {
// Since the DevTools only just became available, we haven't had a chance to
// report their URLs yet. Do so now.
_residentRunner.printDebuggerList(includeVmService: false);
}
+
+ if (isStartPaused) {
+ await callServiceExtensions();
+ }
}
// This must be guaranteed not to return a Future that fails.
@@ -295,7 +319,11 @@
}
@override
- Future<void> serveAndAnnounceDevTools({Uri? devToolsServerAddress, List<FlutterDevice?>? flutterDevices}) async {
+ Future<void> serveAndAnnounceDevTools({
+ Uri? devToolsServerAddress,
+ List<FlutterDevice?>? flutterDevices,
+ bool isStartPaused = false,
+ }) async {
return;
}
diff --git a/packages/flutter_tools/lib/src/run_cold.dart b/packages/flutter_tools/lib/src/run_cold.dart
index 88c3fd6..cbd83be 100644
--- a/packages/flutter_tools/lib/src/run_cold.dart
+++ b/packages/flutter_tools/lib/src/run_cold.dart
@@ -86,6 +86,7 @@
unawaited(residentDevtoolsHandler!.serveAndAnnounceDevTools(
devToolsServerAddress: debuggingOptions.devToolsServerAddress,
flutterDevices: flutterDevices,
+ isStartPaused: debuggingOptions.startPaused,
));
}
if (debuggingOptions.serveObservatory) {
@@ -173,6 +174,7 @@
unawaited(residentDevtoolsHandler!.serveAndAnnounceDevTools(
devToolsServerAddress: debuggingOptions.devToolsServerAddress,
flutterDevices: flutterDevices,
+ isStartPaused: debuggingOptions.startPaused,
));
}
if (debuggingOptions.serveObservatory) {
diff --git a/packages/flutter_tools/lib/src/run_hot.dart b/packages/flutter_tools/lib/src/run_hot.dart
index daf1c46..7d8c77a 100644
--- a/packages/flutter_tools/lib/src/run_hot.dart
+++ b/packages/flutter_tools/lib/src/run_hot.dart
@@ -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 'dart:async';
import 'package:meta/meta.dart';
@@ -251,6 +249,7 @@
unawaited(residentDevtoolsHandler!.serveAndAnnounceDevTools(
devToolsServerAddress: debuggingOptions.devToolsServerAddress,
flutterDevices: flutterDevices,
+ isStartPaused: debuggingOptions.startPaused,
));
}
@@ -1300,9 +1299,8 @@
for (final FlutterView view in views) {
// Check if the isolate is paused, and if so, don't reassemble. Ignore the
// PostPauseEvent event - the client requesting the pause will resume the app.
- final vm_service.Isolate? isolate = await device!.vmService!
- .getIsolateOrNull(view.uiIsolate!.id!);
- final vm_service.Event? pauseEvent = isolate?.pauseEvent;
+ final vm_service.Event? pauseEvent = await device!.vmService!
+ .getIsolatePauseEventOrNull(view.uiIsolate!.id!);
if (pauseEvent != null
&& isPauseEvent(pauseEvent.kind!)
&& pauseEvent.kind != vm_service.EventKind.kPausePostRequest) {
@@ -1366,16 +1364,13 @@
int postReloadPausedIsolatesFound = 0;
String? serviceEventKind;
for (final FlutterView view in reassembleViews.keys) {
- final vm_service.Isolate? isolate = await reassembleViews[view]!
- .getIsolateOrNull(view.uiIsolate!.id!);
- if (isolate == null) {
- continue;
- }
- if (isolate.pauseEvent != null && isPauseEvent(isolate.pauseEvent!.kind!)) {
+ final vm_service.Event? pauseEvent = await reassembleViews[view]!
+ .getIsolatePauseEventOrNull(view.uiIsolate!.id!);
+ if (pauseEvent != null && isPauseEvent(pauseEvent.kind!)) {
postReloadPausedIsolatesFound += 1;
if (serviceEventKind == null) {
- serviceEventKind = isolate.pauseEvent!.kind;
- } else if (serviceEventKind != isolate.pauseEvent!.kind) {
+ serviceEventKind = pauseEvent.kind;
+ } else if (serviceEventKind != pauseEvent.kind) {
serviceEventKind = ''; // many kinds
}
}
diff --git a/packages/flutter_tools/lib/src/runner/flutter_command.dart b/packages/flutter_tools/lib/src/runner/flutter_command.dart
index a099d81..b7e624b 100644
--- a/packages/flutter_tools/lib/src/runner/flutter_command.dart
+++ b/packages/flutter_tools/lib/src/runner/flutter_command.dart
@@ -612,17 +612,17 @@
valueHelp: 'foo=bar',
splitCommas: false,
);
- useDartDefineConfigJsonFileOption();
+ useDartDefineFromFileOption();
}
- void useDartDefineConfigJsonFileOption() {
+ void useDartDefineFromFileOption() {
argParser.addMultiOption(
FlutterOptions.kDartDefineFromFileOption,
- help: 'The path of a json format file where flutter define a global constant pool. '
- 'Json entry will be available as constants from the String.fromEnvironment, bool.fromEnvironment, '
- 'and int.fromEnvironment constructors; the key and field are json values.\n'
+ help:
+ 'The path of a .json or .env file containing key-value pairs that will be available as environment variables.\n'
+ 'These can be accessed using the String.fromEnvironment, bool.fromEnvironment, and int.fromEnvironment constructors.\n'
'Multiple defines can be passed by repeating "--${FlutterOptions.kDartDefineFromFileOption}" multiple times.',
- valueHelp: 'use-define-config.json',
+ valueHelp: 'use-define-config.json|.env',
splitCommas: false,
);
}
@@ -1190,7 +1190,7 @@
? stringArg(FlutterOptions.kPerformanceMeasurementFile)
: null;
- final Map<String, Object>? defineConfigJsonMap = extractDartDefineConfigJsonMap();
+ final Map<String, Object?> defineConfigJsonMap = extractDartDefineConfigJsonMap();
List<String> dartDefines = extractDartDefines(defineConfigJsonMap: defineConfigJsonMap);
WebRendererMode webRenderer = WebRendererMode.auto;
@@ -1323,44 +1323,52 @@
}
}
- List<String> extractDartDefines({Map<String, Object>? defineConfigJsonMap}) {
+ List<String> extractDartDefines({required Map<String, Object?> defineConfigJsonMap}) {
final List<String> dartDefines = <String>[];
if (argParser.options.containsKey(FlutterOptions.kDartDefinesOption)) {
dartDefines.addAll(stringsArg(FlutterOptions.kDartDefinesOption));
}
- if (defineConfigJsonMap == null) {
- return dartDefines;
- }
- defineConfigJsonMap.forEach((String key, Object value) {
+ defineConfigJsonMap.forEach((String key, Object? value) {
dartDefines.add('$key=$value');
});
return dartDefines;
}
- Map<String, Object>? extractDartDefineConfigJsonMap() {
- final Map<String, Object> dartDefineConfigJsonMap = <String, Object>{};
+ Map<String, Object?> extractDartDefineConfigJsonMap() {
+ final Map<String, Object?> dartDefineConfigJsonMap = <String, Object?>{};
if (argParser.options.containsKey(FlutterOptions.kDartDefineFromFileOption)) {
- final List<String> configJsonPaths = stringsArg(
- FlutterOptions.kDartDefineFromFileOption,
+ final List<String> configFilePaths = stringsArg(
+ FlutterOptions.kDartDefineFromFileOption,
);
- for (final String path in configJsonPaths) {
+ for (final String path in configFilePaths) {
if (!globals.fs.isFileSync(path)) {
throwToolExit('Json config define file "--${FlutterOptions
.kDartDefineFromFileOption}=$path" is not a file, '
'please fix first!');
}
- final String configJsonRaw = globals.fs.file(path).readAsStringSync();
+ final String configRaw = globals.fs.file(path).readAsStringSync();
+
+ // Determine whether the file content is JSON or .env format.
+ String configJsonRaw;
+ if (configRaw.trim().startsWith('{')) {
+ configJsonRaw = configRaw;
+ } else {
+
+ // Convert env file to JSON.
+ configJsonRaw = convertEnvFileToJsonRaw(configRaw);
+ }
+
try {
// Fix json convert Object value :type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Map<String, Object>' in type cast
(json.decode(configJsonRaw) as Map<String, dynamic>)
- .forEach((String key, dynamic value) {
- dartDefineConfigJsonMap[key] = value as Object;
+ .forEach((String key, Object? value) {
+ dartDefineConfigJsonMap[key] = value;
});
} on FormatException catch (err) {
throwToolExit('Json config define file "--${FlutterOptions
@@ -1373,6 +1381,88 @@
return dartDefineConfigJsonMap;
}
+ /// Parse a property line from an env file.
+ /// Supposed property structure should be:
+ /// key=value
+ ///
+ /// Where: key is a string without spaces and value is a string.
+ /// Value can also contain '=' char.
+ ///
+ /// Returns a record of key and value as strings.
+ MapEntry<String, String> _parseProperty(String line) {
+ final RegExp blockRegExp = RegExp(r'^\s*([a-zA-Z_]+[a-zA-Z0-9_]*)\s*=\s*"""\s*(.*)$');
+ if (blockRegExp.hasMatch(line)) {
+ throwToolExit('Multi-line value is not supported: $line');
+ }
+
+ final RegExp propertyRegExp = RegExp(r'^\s*([a-zA-Z_]+[a-zA-Z0-9_]*)\s*=\s*(.*)?$');
+ final Match? match = propertyRegExp.firstMatch(line);
+ if (match == null) {
+ throwToolExit('Unable to parse file provided for '
+ '--${FlutterOptions.kDartDefineFromFileOption}.\n'
+ 'Invalid property line: $line');
+ }
+
+ final String key = match.group(1)!;
+ final String value = match.group(2) ?? '';
+
+ // Remove wrapping quotes and trailing line comment.
+ final RegExp doubleQuoteValueRegExp = RegExp(r'^"(.*)"\s*(\#\s*.*)?$');
+ final Match? doubleQuoteValue = doubleQuoteValueRegExp.firstMatch(value);
+ if (doubleQuoteValue != null) {
+ return MapEntry<String, String>(key, doubleQuoteValue.group(1)!);
+ }
+
+ final RegExp quoteValueRegExp = RegExp(r"^'(.*)'\s*(\#\s*.*)?$");
+ final Match? quoteValue = quoteValueRegExp.firstMatch(value);
+ if (quoteValue != null) {
+ return MapEntry<String, String>(key, quoteValue.group(1)!);
+ }
+
+ final RegExp backQuoteValueRegExp = RegExp(r'^`(.*)`\s*(\#\s*.*)?$');
+ final Match? backQuoteValue = backQuoteValueRegExp.firstMatch(value);
+ if (backQuoteValue != null) {
+ return MapEntry<String, String>(key, backQuoteValue.group(1)!);
+ }
+
+ final RegExp noQuoteValueRegExp = RegExp(r'^([^#\n\s]*)\s*(?:\s*#\s*(.*))?$');
+ final Match? noQuoteValue = noQuoteValueRegExp.firstMatch(value);
+ if (noQuoteValue != null) {
+ return MapEntry<String, String>(key, noQuoteValue.group(1)!);
+ }
+
+ return MapEntry<String, String>(key, value);
+ }
+
+ /// Converts an .env file string to its equivalent JSON string.
+ ///
+ /// For example, the .env file string
+ /// key=value # comment
+ /// complexKey="foo#bar=baz"
+ /// would be converted to a JSON string equivalent to:
+ /// {
+ /// "key": "value",
+ /// "complexKey": "foo#bar=baz"
+ /// }
+ ///
+ /// Multiline values are not supported.
+ String convertEnvFileToJsonRaw(String configRaw) {
+ final List<String> lines = configRaw
+ .split('\n')
+ .map((String line) => line.trim())
+ .where((String line) => line.isNotEmpty)
+ .where((String line) => !line.startsWith('#')) // Remove comment lines.
+ .toList();
+
+ final Map<String, String> propertyMap = <String, String>{};
+ for (final String line in lines) {
+ final MapEntry<String, String> property = _parseProperty(line);
+ propertyMap[property.key] = property.value;
+ }
+
+ return jsonEncode(propertyMap);
+ }
+
/// Updates dart-defines based on [webRenderer].
@visibleForTesting
static List<String> updateDartDefines(List<String> dartDefines, WebRendererMode webRenderer) {
diff --git a/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart b/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart
index 9f10cd0..5d6d786 100644
--- a/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart
+++ b/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart
@@ -18,6 +18,7 @@
import '../convert.dart';
import '../globals.dart' as globals;
import '../tester/flutter_tester.dart';
+import '../version.dart';
import '../web/web_device.dart';
/// Common flutter command line options.
@@ -318,14 +319,16 @@
if ((topLevelResults[FlutterGlobalOptions.kVersionFlag] as bool?) ?? false) {
globals.flutterUsage.sendCommand(FlutterGlobalOptions.kVersionFlag);
- globals.flutterVersion.fetchTagsAndUpdate();
- String status;
+ final FlutterVersion version = globals.flutterVersion.fetchTagsAndGetVersion(
+ clock: globals.systemClock,
+ );
+ final String status;
if (machineFlag) {
- final Map<String, Object> jsonOut = globals.flutterVersion.toJson();
+ final Map<String, Object> jsonOut = version.toJson();
jsonOut['flutterRoot'] = Cache.flutterRoot!;
status = const JsonEncoder.withIndent(' ').convert(jsonOut);
} else {
- status = globals.flutterVersion.toString();
+ status = version.toString();
}
globals.printStatus(status);
return;
diff --git a/packages/flutter_tools/lib/src/runner/target_devices.dart b/packages/flutter_tools/lib/src/runner/target_devices.dart
index b0697d0..202ac90 100644
--- a/packages/flutter_tools/lib/src/runner/target_devices.dart
+++ b/packages/flutter_tools/lib/src/runner/target_devices.dart
@@ -774,7 +774,7 @@
throwToolExit('');
}
final int deviceIndex = int.parse(userInputString) - 1;
- if (deviceIndex < devices.length) {
+ if (deviceIndex > -1 && deviceIndex < devices.length) {
chosenDevice = devices[deviceIndex];
}
}
diff --git a/packages/flutter_tools/lib/src/version.dart b/packages/flutter_tools/lib/src/version.dart
index bae196f..0702b35 100644
--- a/packages/flutter_tools/lib/src/version.dart
+++ b/packages/flutter_tools/lib/src/version.dart
@@ -79,104 +79,153 @@
return null;
}
-class FlutterVersion {
+abstract class FlutterVersion {
/// Parses the Flutter version from currently available tags in the local
/// repo.
- ///
- /// Call [fetchTagsAndUpdate] to update the version based on the latest tags
- /// available upstream.
- FlutterVersion({
+ factory FlutterVersion({
SystemClock clock = const SystemClock(),
- String? workingDirectory,
- String? frameworkRevision,
- }) : _clock = clock,
- _workingDirectory = workingDirectory {
- _frameworkRevision = frameworkRevision ?? _runGit(
- gitLog(<String>['-n', '1', '--pretty=format:%H']).join(' '),
- globals.processUtils,
- _workingDirectory,
- );
- _gitTagVersion = GitTagVersion.determine(globals.processUtils, globals.platform, workingDirectory: _workingDirectory, gitRef: _frameworkRevision);
- _frameworkVersion = gitTagVersion.frameworkVersionFor(_frameworkRevision);
- }
+ required FileSystem fs,
+ required String flutterRoot,
+ @protected
+ bool fetchTags = false,
+ }) {
+ final File versionFile = getVersionFile(fs, flutterRoot);
- final SystemClock _clock;
- final String? _workingDirectory;
-
- /// Fetches tags from the upstream Flutter repository and re-calculates the
- /// version.
- ///
- /// This carries a performance penalty, and should only be called when the
- /// user explicitly wants to get the version, e.g. for `flutter --version` or
- /// `flutter doctor`.
- void fetchTagsAndUpdate() {
- _gitTagVersion = GitTagVersion.determine(globals.processUtils, globals.platform, workingDirectory: _workingDirectory, fetchTags: true);
- _frameworkVersion = gitTagVersion.frameworkVersionFor(_frameworkRevision);
- }
-
- String? _repositoryUrl;
- String? get repositoryUrl {
- if (_repositoryUrl == null) {
- final String gitChannel = _runGit(
- 'git rev-parse --abbrev-ref --symbolic $kGitTrackingUpstream',
- globals.processUtils,
- _workingDirectory,
+ if (!fetchTags && versionFile.existsSync()) {
+ final _FlutterVersionFromFile? version = _FlutterVersionFromFile.tryParseFromFile(
+ versionFile,
+ flutterRoot: flutterRoot,
);
- final int slash = gitChannel.indexOf('/');
- if (slash != -1) {
- final String remote = gitChannel.substring(0, slash);
- _repositoryUrl = _runGit(
- 'git ls-remote --get-url $remote',
- globals.processUtils,
- _workingDirectory,
- );
+ if (version != null) {
+ return version;
}
}
- return _repositoryUrl;
- }
- /// The channel is the current branch if we recognize it, or "[user-branch]" (kUserBranch).
- /// `master`, `beta`, `stable`; or old ones, like `alpha`, `hackathon`, `dev`, ...
- String get channel {
- final String channel = getBranchName(redactUnknownBranches: true);
- assert(kOfficialChannels.contains(channel) || kObsoleteBranches.containsKey(channel) || channel == kUserBranch, 'Potential PII leak in channel name: "$channel"');
- return channel;
- }
+ // if we are fetching tags, ignore cached versionFile
+ if (fetchTags && versionFile.existsSync()) {
+ versionFile.deleteSync();
+ final File legacyVersionFile = fs.file(fs.path.join(flutterRoot, 'version'));
+ if (legacyVersionFile.existsSync()) {
+ legacyVersionFile.deleteSync();
+ }
+ }
- late GitTagVersion _gitTagVersion;
- GitTagVersion get gitTagVersion => _gitTagVersion;
-
- /// The name of the local branch.
- /// Use getBranchName() to read this.
- String? _branch;
-
- late String _frameworkRevision;
- String get frameworkRevision => _frameworkRevision;
- String get frameworkRevisionShort => _shortGitRevision(frameworkRevision);
-
- String? _frameworkAge;
- String get frameworkAge {
- return _frameworkAge ??= _runGit(
- gitLog(<String>['-n', '1', '--pretty=format:%ar']).join(' '),
+ final String frameworkRevision = _runGit(
+ gitLog(<String>['-n', '1', '--pretty=format:%H']).join(' '),
globals.processUtils,
- _workingDirectory,
+ flutterRoot,
+ );
+
+ return FlutterVersion.fromRevision(
+ clock: clock,
+ frameworkRevision: frameworkRevision,
+ fs: fs,
+ flutterRoot: flutterRoot,
+ fetchTags: fetchTags,
);
}
- late String _frameworkVersion;
- String get frameworkVersion => _frameworkVersion;
+ FlutterVersion._({
+ required SystemClock clock,
+ required this.flutterRoot,
+ required this.fs,
+ }) : _clock = clock;
- String get devToolsVersion => globals.cache.devToolsVersion;
+ factory FlutterVersion.fromRevision({
+ SystemClock clock = const SystemClock(),
+ required String flutterRoot,
+ required String frameworkRevision,
+ required FileSystem fs,
+ bool fetchTags = false,
+ }) {
+ final GitTagVersion gitTagVersion = GitTagVersion.determine(
+ globals.processUtils,
+ globals.platform,
+ gitRef: frameworkRevision,
+ workingDirectory: flutterRoot,
+ fetchTags: fetchTags,
+ );
+ final String frameworkVersion = gitTagVersion.frameworkVersionFor(frameworkRevision);
+ return _FlutterVersionGit._(
+ clock: clock,
+ flutterRoot: flutterRoot,
+ frameworkRevision: frameworkRevision,
+ frameworkVersion: frameworkVersion,
+ gitTagVersion: gitTagVersion,
+ fs: fs,
+ );
+ }
- String get dartSdkVersion => globals.cache.dartSdkVersion;
+ /// Ensure the latest git tags are fetched and recalculate [FlutterVersion].
+ ///
+ /// This is only required when not on beta or stable and we need to calculate
+ /// the current version relative to upstream tags.
+ ///
+ /// This is a method and not a factory constructor so that test classes can
+ /// override it.
+ FlutterVersion fetchTagsAndGetVersion({
+ SystemClock clock = const SystemClock(),
+ }) {
+ // We don't need to fetch tags on beta and stable to calculate the version,
+ // we should already exactly be on a tag that was pushed when this release
+ // was published.
+ if (channel != 'master' && channel != 'main') {
+ return this;
+ }
+ return FlutterVersion(
+ clock: clock,
+ flutterRoot: flutterRoot,
+ fs: fs,
+ fetchTags: true,
+ );
+ }
- String get engineRevision => globals.cache.engineRevision;
+ final FileSystem fs;
+
+ final SystemClock _clock;
+
+ String? get repositoryUrl;
+
+ GitTagVersion get gitTagVersion;
+
+ /// The channel is the upstream branch.
+ ///
+ /// `master`, `dev`, `beta`, `stable`; or old ones, like `alpha`, `hackathon`, ...
+ String get channel;
+
+ String get frameworkRevision;
+ String get frameworkRevisionShort => _shortGitRevision(frameworkRevision);
+
+ String get frameworkVersion;
+
+ String get devToolsVersion;
+
+ String get dartSdkVersion;
+
+ String get engineRevision;
String get engineRevisionShort => _shortGitRevision(engineRevision);
- void ensureVersionFile() {
- globals.fs.file(globals.fs.path.join(Cache.flutterRoot!, 'version')).writeAsStringSync(_frameworkVersion);
+ // This is static as it is called from a constructor.
+ static File getVersionFile(FileSystem fs, String flutterRoot) {
+ return fs.file(fs.path.join(flutterRoot, 'bin', 'cache', 'flutter.version.json'));
}
+ final String flutterRoot;
+
+ String? _frameworkAge;
+
+ // TODO(fujino): calculate this relative to frameworkCommitDate for
+ // _FlutterVersionFromFile so we don't need a git call.
+ String get frameworkAge {
+ return _frameworkAge ??= _runGit(
+ FlutterVersion.gitLog(<String>['-n', '1', '--pretty=format:%ar']).join(' '),
+ globals.processUtils,
+ flutterRoot,
+ );
+ }
+
+ void ensureVersionFile();
+
@override
String toString() {
final String versionText = frameworkVersion == _unknownFrameworkVersion ? '' : ' $frameworkVersion';
@@ -202,47 +251,13 @@
'engineRevision': engineRevision,
'dartSdkVersion': dartSdkVersion,
'devToolsVersion': devToolsVersion,
+ 'flutterVersion': frameworkVersion,
};
- String get frameworkDate => frameworkCommitDate;
-
/// A date String describing the last framework commit.
///
/// If a git command fails, this will return a placeholder date.
- String get frameworkCommitDate => _gitCommitDate(lenient: true);
-
- // The date of the given commit hash as [gitRef]. If no hash is specified,
- // then it is the HEAD of the current local branch.
- //
- // If lenient is true, and the git command fails, a placeholder date is
- // returned. Otherwise, the VersionCheckError exception is propagated.
- static String _gitCommitDate({
- String gitRef = 'HEAD',
- bool lenient = false,
- }) {
- final List<String> args = gitLog(<String>[
- gitRef,
- '-n',
- '1',
- '--pretty=format:%ad',
- '--date=iso',
- ]);
- try {
- // Don't plumb 'lenient' through directly so that we can print an error
- // if something goes wrong.
- return _runSync(args, lenient: false);
- } on VersionCheckError catch (e) {
- if (lenient) {
- final DateTime dummyDate = DateTime.fromMillisecondsSinceEpoch(0);
- globals.printError('Failed to find the latest git commit date: $e\n'
- 'Returning $dummyDate instead.');
- // Return something that DateTime.parse() can parse.
- return dummyDate.toString();
- } else {
- rethrow;
- }
- }
- }
+ String get frameworkCommitDate;
/// Checks if the currently installed version of Flutter is up-to-date, and
/// warns the user if it isn't.
@@ -261,7 +276,7 @@
DateTime localFrameworkCommitDate;
try {
// Don't perform the update check if fetching the latest local commit failed.
- localFrameworkCommitDate = DateTime.parse(_gitCommitDate());
+ localFrameworkCommitDate = DateTime.parse(_gitCommitDate(workingDirectory: flutterRoot));
} on VersionCheckError {
return;
}
@@ -278,6 +293,53 @@
).run();
}
+ /// Gets the release date of the latest available Flutter version.
+ ///
+ /// This method sends a server request if it's been more than
+ /// [checkAgeConsideredUpToDate] since the last version check.
+ ///
+ /// Returns null if the cached version is out-of-date or missing, and we are
+ /// unable to reach the server to get the latest version.
+ Future<DateTime?> _getLatestAvailableFlutterDate() async {
+ globals.cache.checkLockAcquired();
+ final VersionCheckStamp versionCheckStamp = await VersionCheckStamp.load(globals.cache, globals.logger);
+
+ final DateTime now = _clock.now();
+ if (versionCheckStamp.lastTimeVersionWasChecked != null) {
+ final Duration timeSinceLastCheck = now.difference(
+ versionCheckStamp.lastTimeVersionWasChecked!,
+ );
+
+ // Don't ping the server too often. Return cached value if it's fresh.
+ if (timeSinceLastCheck < VersionFreshnessValidator.checkAgeConsideredUpToDate) {
+ return versionCheckStamp.lastKnownRemoteVersion;
+ }
+ }
+
+ // Cache is empty or it's been a while since the last server ping. Ping the server.
+ try {
+ final DateTime remoteFrameworkCommitDate = DateTime.parse(
+ await fetchRemoteFrameworkCommitDate(),
+ );
+ await versionCheckStamp.store(
+ newTimeVersionWasChecked: now,
+ newKnownRemoteVersion: remoteFrameworkCommitDate,
+ );
+ return remoteFrameworkCommitDate;
+ } on VersionCheckError catch (error) {
+ // This happens when any of the git commands fails, which can happen when
+ // there's no Internet connectivity. Remote version check is best effort
+ // only. We do not prevent the command from running when it fails.
+ globals.printTrace('Failed to check Flutter version in the remote repository: $error');
+ // Still update the timestamp to avoid us hitting the server on every single
+ // command if for some reason we cannot connect (eg. we may be offline).
+ await versionCheckStamp.store(
+ newTimeVersionWasChecked: now,
+ );
+ return null;
+ }
+ }
+
/// The date of the latest framework commit in the remote repository.
///
/// Throws [VersionCheckError] if a git command fails, for example, when the
@@ -286,7 +348,7 @@
try {
// Fetch upstream branch's commit and tags
await _run(<String>['git', 'fetch', '--tags']);
- return _gitCommitDate(gitRef: kGitTrackingUpstream);
+ return _gitCommitDate(gitRef: kGitTrackingUpstream, workingDirectory: Cache.flutterRoot);
} on VersionCheckError catch (error) {
globals.printError(error.message);
rethrow;
@@ -301,13 +363,18 @@
return '${getBranchName(redactUnknownBranches: redactUnknownBranches)}/$frameworkRevisionShort';
}
+ /// The name of the local branch.
+ ///
+ /// Use getBranchName() to read this.
+ String? _branch;
+
/// Return the branch name.
///
/// If [redactUnknownBranches] is true and the branch is unknown,
/// the branch name will be returned as `'[user-branch]'` ([kUserBranch]).
String getBranchName({ bool redactUnknownBranches = false }) {
_branch ??= () {
- final String branch = _runGit('git symbolic-ref --short HEAD', globals.processUtils, _workingDirectory);
+ final String branch = _runGit('git symbolic-ref --short HEAD', globals.processUtils, flutterRoot);
return branch == 'HEAD' ? '' : branch;
}();
if (redactUnknownBranches || _branch!.isEmpty) {
@@ -342,51 +409,205 @@
static List<String> gitLog(List<String> args) {
return <String>['git', '-c', 'log.showSignature=false', 'log'] + args;
}
+}
- /// Gets the release date of the latest available Flutter version.
- ///
- /// This method sends a server request if it's been more than
- /// [checkAgeConsideredUpToDate] since the last version check.
- ///
- /// Returns null if the cached version is out-of-date or missing, and we are
- /// unable to reach the server to get the latest version.
- Future<DateTime?> _getLatestAvailableFlutterDate() async {
- globals.cache.checkLockAcquired();
- final VersionCheckStamp versionCheckStamp = await VersionCheckStamp.load(globals.cache, globals.logger);
+// The date of the given commit hash as [gitRef]. If no hash is specified,
+// then it is the HEAD of the current local branch.
+//
+// If lenient is true, and the git command fails, a placeholder date is
+// returned. Otherwise, the VersionCheckError exception is propagated.
+String _gitCommitDate({
+ String gitRef = 'HEAD',
+ bool lenient = false,
+ required String? workingDirectory,
+}) {
+ final List<String> args = FlutterVersion.gitLog(<String>[
+ gitRef,
+ '-n',
+ '1',
+ '--pretty=format:%ad',
+ '--date=iso',
+ ]);
+ try {
+ // Don't plumb 'lenient' through directly so that we can print an error
+ // if something goes wrong.
+ return _runSync(
+ args,
+ lenient: false,
+ workingDirectory: workingDirectory,
+ );
+ } on VersionCheckError catch (e) {
+ if (lenient) {
+ final DateTime dummyDate = DateTime.fromMillisecondsSinceEpoch(0);
+ globals.printError('Failed to find the latest git commit date: $e\n'
+ 'Returning $dummyDate instead.');
+ // Return something that DateTime.parse() can parse.
+ return dummyDate.toString();
+ } else {
+ rethrow;
+ }
+ }
+}
- final DateTime now = _clock.now();
- if (versionCheckStamp.lastTimeVersionWasChecked != null) {
- final Duration timeSinceLastCheck = now.difference(
- versionCheckStamp.lastTimeVersionWasChecked!,
+class _FlutterVersionFromFile extends FlutterVersion {
+ _FlutterVersionFromFile._({
+ required super.clock,
+ required this.frameworkVersion,
+ required this.channel,
+ required this.repositoryUrl,
+ required this.frameworkRevision,
+ required this.frameworkCommitDate,
+ required this.engineRevision,
+ required this.dartSdkVersion,
+ required this.devToolsVersion,
+ required this.gitTagVersion,
+ required super.flutterRoot,
+ required super.fs,
+ }) : super._();
+
+ static _FlutterVersionFromFile? tryParseFromFile(
+ File jsonFile, {
+ required String flutterRoot,
+ SystemClock clock = const SystemClock(),
+ }) {
+ try {
+ final String jsonContents = jsonFile.readAsStringSync();
+ final Map<String, Object?> manifest = jsonDecode(jsonContents) as Map<String, Object?>;
+
+ return _FlutterVersionFromFile._(
+ clock: clock,
+ frameworkVersion: manifest['frameworkVersion']! as String,
+ channel: manifest['channel']! as String,
+ repositoryUrl: manifest['repositoryUrl']! as String,
+ frameworkRevision: manifest['frameworkRevision']! as String,
+ frameworkCommitDate: manifest['frameworkCommitDate']! as String,
+ engineRevision: manifest['engineRevision']! as String,
+ dartSdkVersion: manifest['dartSdkVersion']! as String,
+ devToolsVersion: manifest['devToolsVersion']! as String,
+ gitTagVersion: GitTagVersion.parse(manifest['flutterVersion']! as String),
+ flutterRoot: flutterRoot,
+ fs: jsonFile.fileSystem,
);
+ // ignore: avoid_catches_without_on_clauses
+ } catch (err) {
+ globals.printTrace('Failed to parse ${jsonFile.path} with $err');
+ try {
+ jsonFile.deleteSync();
+ } on FileSystemException {
+ globals.printTrace('Failed to delete ${jsonFile.path}');
+ }
+ // Returning null means fallback to git implementation.
+ return null;
+ }
+ }
- // Don't ping the server too often. Return cached value if it's fresh.
- if (timeSinceLastCheck < VersionFreshnessValidator.checkAgeConsideredUpToDate) {
- return versionCheckStamp.lastKnownRemoteVersion;
+ @override
+ final GitTagVersion gitTagVersion;
+
+ @override
+ final String frameworkVersion;
+
+ @override
+ final String channel;
+
+ @override
+ String getBranchName({bool redactUnknownBranches = false}) => channel;
+
+ @override
+ final String repositoryUrl;
+
+ @override
+ final String frameworkRevision;
+
+ @override
+ final String frameworkCommitDate;
+
+ @override
+ final String engineRevision;
+
+ @override
+ final String dartSdkVersion;
+
+ @override
+ final String devToolsVersion;
+
+ @override
+ void ensureVersionFile() {}
+}
+
+class _FlutterVersionGit extends FlutterVersion {
+ _FlutterVersionGit._({
+ required super.clock,
+ required super.flutterRoot,
+ required this.frameworkRevision,
+ required this.frameworkVersion,
+ required this.gitTagVersion,
+ required super.fs,
+ }) : super._();
+
+ @override
+ final GitTagVersion gitTagVersion;
+
+ @override
+ final String frameworkRevision;
+
+ @override
+ String get frameworkCommitDate => _gitCommitDate(lenient: true, workingDirectory: flutterRoot);
+
+ String? _repositoryUrl;
+ @override
+ String? get repositoryUrl {
+ if (_repositoryUrl == null) {
+ final String gitChannel = _runGit(
+ 'git rev-parse --abbrev-ref --symbolic $kGitTrackingUpstream',
+ globals.processUtils,
+ flutterRoot,
+ );
+ final int slash = gitChannel.indexOf('/');
+ if (slash != -1) {
+ final String remote = gitChannel.substring(0, slash);
+ _repositoryUrl = _runGit(
+ 'git ls-remote --get-url $remote',
+ globals.processUtils,
+ flutterRoot,
+ );
}
}
+ return _repositoryUrl;
+ }
- // Cache is empty or it's been a while since the last server ping. Ping the server.
- try {
- final DateTime remoteFrameworkCommitDate = DateTime.parse(
- await FlutterVersion.fetchRemoteFrameworkCommitDate(),
- );
- await versionCheckStamp.store(
- newTimeVersionWasChecked: now,
- newKnownRemoteVersion: remoteFrameworkCommitDate,
- );
- return remoteFrameworkCommitDate;
- } on VersionCheckError catch (error) {
- // This happens when any of the git commands fails, which can happen when
- // there's no Internet connectivity. Remote version check is best effort
- // only. We do not prevent the command from running when it fails.
- globals.printTrace('Failed to check Flutter version in the remote repository: $error');
- // Still update the timestamp to avoid us hitting the server on every single
- // command if for some reason we cannot connect (eg. we may be offline).
- await versionCheckStamp.store(
- newTimeVersionWasChecked: now,
- );
- return null;
+ @override
+ String get devToolsVersion => globals.cache.devToolsVersion;
+
+ @override
+ String get dartSdkVersion => globals.cache.dartSdkVersion;
+
+ @override
+ String get engineRevision => globals.cache.engineRevision;
+
+ @override
+ final String frameworkVersion;
+
+ /// The channel is the current branch if we recognize it, or "[user-branch]" (kUserBranch).
+ /// `master`, `beta`, `stable`; or old ones, like `alpha`, `hackathon`, `dev`, ...
+ @override
+ String get channel {
+ final String channel = getBranchName(redactUnknownBranches: true);
+ assert(kOfficialChannels.contains(channel) || kObsoleteBranches.containsKey(channel) || channel == kUserBranch, 'Potential PII leak in channel name: "$channel"');
+ return channel;
+ }
+
+ @override
+ void ensureVersionFile() {
+ final File legacyVersionFile = fs.file(fs.path.join(flutterRoot, 'version'));
+ if (!legacyVersionFile.existsSync()) {
+ legacyVersionFile.writeAsStringSync(frameworkVersion);
+ }
+
+ const JsonEncoder encoder = JsonEncoder.withIndent(' ');
+ final File newVersionFile = FlutterVersion.getVersionFile(fs, flutterRoot);
+ if (!newVersionFile.existsSync()) {
+ newVersionFile.writeAsStringSync(encoder.convert(toJson()));
}
}
}
@@ -606,10 +827,14 @@
///
/// If [lenient] is true and the command fails, returns an empty string.
/// Otherwise, throws a [ToolExit] exception.
-String _runSync(List<String> command, { bool lenient = true }) {
+String _runSync(
+ List<String> command, {
+ bool lenient = true,
+ required String? workingDirectory,
+}) {
final ProcessResult results = globals.processManager.runSync(
command,
- workingDirectory: Cache.flutterRoot,
+ workingDirectory: workingDirectory,
);
if (results.exitCode == 0) {
@@ -630,7 +855,7 @@
String _runGit(String command, ProcessUtils processUtils, String? workingDirectory) {
return processUtils.runSync(
command.split(' '),
- workingDirectory: workingDirectory ?? Cache.flutterRoot,
+ workingDirectory: workingDirectory,
).stdout.trim();
}
diff --git a/packages/flutter_tools/lib/src/vmservice.dart b/packages/flutter_tools/lib/src/vmservice.dart
index 9f9d596..6da8494 100644
--- a/packages/flutter_tools/lib/src/vmservice.dart
+++ b/packages/flutter_tools/lib/src/vmservice.dart
@@ -13,8 +13,10 @@
import 'base/io.dart' as io;
import 'base/logger.dart';
import 'base/utils.dart';
+import 'cache.dart';
import 'convert.dart';
import 'device.dart';
+import 'globals.dart' as globals;
import 'ios/xcodeproj.dart';
import 'project.dart';
import 'version.dart';
@@ -244,7 +246,10 @@
}
vmService.registerServiceCallback(kFlutterVersionServiceName, (Map<String, Object?> params) async {
- final FlutterVersion version = context.get<FlutterVersion>() ?? FlutterVersion();
+ final FlutterVersion version = context.get<FlutterVersion>() ?? FlutterVersion(
+ fs: globals.fs,
+ flutterRoot: Cache.flutterRoot!,
+ );
final Map<String, Object> versionJson = version.toJson();
versionJson['frameworkRevisionShort'] = version.frameworkRevisionShort;
versionJson['engineRevisionShort'] = version.engineRevisionShort;
@@ -1105,6 +1110,22 @@
});
}
+ /// Attempt to retrieve the isolate pause event with id [isolateId], or `null` if it has
+ /// been collected.
+ Future<vm_service.Event?> getIsolatePauseEventOrNull(String isolateId) async {
+ return service.getIsolatePauseEvent(isolateId)
+ .then<vm_service.Event?>(
+ (vm_service.Event event) => event,
+ onError: (Object? error, StackTrace stackTrace) {
+ if (error is vm_service.SentinelException ||
+ error == null ||
+ (error is vm_service.RPCError && error.code == RPCErrorCodes.kServiceDisappeared)) {
+ return null;
+ }
+ return Future<vm_service.Event?>.error(error, stackTrace);
+ });
+ }
+
/// Create a new development file system on the device.
Future<vm_service.Response> createDevFS(String fsName) {
// Call the unchecked version of `callServiceExtension` because the caller
diff --git a/packages/flutter_tools/lib/src/web/bootstrap.dart b/packages/flutter_tools/lib/src/web/bootstrap.dart
index 53ef4bf..5f5f6d1 100644
--- a/packages/flutter_tools/lib/src/web/bootstrap.dart
+++ b/packages/flutter_tools/lib/src/web/bootstrap.dart
@@ -196,6 +196,12 @@
return dart.getSourceMap(url);
});
}
+ // Prevent DDC's requireJS to interfere with modern bundling.
+ if (typeof define === 'function' && define.amd) {
+ // Preserve a copy just in case...
+ define._amd = define.amd;
+ delete define.amd;
+ }
});
''';
}
diff --git a/packages/flutter_tools/pubspec.yaml b/packages/flutter_tools/pubspec.yaml
index 1a68653..39b142c 100644
--- a/packages/flutter_tools/pubspec.yaml
+++ b/packages/flutter_tools/pubspec.yaml
@@ -10,8 +10,8 @@
archive: 3.3.2
args: 2.4.2
browser_launcher: 1.1.1
- dds: 2.9.0
- dwds: 19.0.0
+ dds: 2.9.2
+ dwds: 19.0.2
completion: 1.0.1
coverage: 1.6.3
crypto: 3.0.3
@@ -26,7 +26,7 @@
package_config: 2.1.0
process: 4.2.4
fake_async: 1.3.1
- stack_trace: 1.11.0
+ stack_trace: 1.11.1
usage: 4.1.1
webdriver: 3.0.2
webkit_inspection_protocol: 1.2.0
@@ -34,10 +34,10 @@
yaml: 3.1.2
native_stack_traces: 0.5.6
shelf: 1.4.1
- vm_snapshot_analysis: 0.7.2
+ vm_snapshot_analysis: 0.7.6
uuid: 3.0.7
web_socket_channel: 2.4.0
- stream_channel: 2.1.1
+ stream_channel: 2.1.2
shelf_web_socket: 1.0.4
shelf_static: 1.1.2
pub_semver: 2.1.4
@@ -48,28 +48,29 @@
http_multi_server: 3.2.1
convert: 3.1.1
async: 2.11.0
- unified_analytics: 2.0.0
+ unified_analytics: 3.0.0
# We depend on very specific internal implementation details of the
# 'test' package, which change between versions, so when upgrading
# this, make sure the tests are still running correctly.
- test_api: 0.6.0
- test_core: 0.5.3
+ test_api: 0.6.1
+ test_core: 0.5.4
- vm_service: 11.6.0
+ vm_service: 11.7.2
standard_message_codec: 0.0.1+3
- _fe_analyzer_shared: 61.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- analyzer: 5.13.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ _fe_analyzer_shared: 62.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ analyzer: 6.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
built_collection: 5.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
built_value: 8.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
clock: 1.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
csslib: 1.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- dap: 1.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- dds_service_extensions: 1.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- devtools_shared: 2.24.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ dap: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ dart_internal: 0.2.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ dds_service_extensions: 1.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ devtools_shared: 2.25.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
fixnum: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
frontend_server_client: 3.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
glob: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -100,10 +101,10 @@
checked_yaml: 2.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
json_annotation: 4.8.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
node_preamble: 2.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test: 1.24.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test: 1.24.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dartdoc:
# Exclude this package from the hosted API docs.
nodoc: true
-# PUBSPEC CHECKSUM: 0694
+# PUBSPEC CHECKSUM: 5e34
diff --git a/packages/flutter_tools/templates/app_shared/analysis_options.yaml.tmpl b/packages/flutter_tools/templates/app_shared/analysis_options.yaml.tmpl
index d78ad1b..7a98d8c 100644
--- a/packages/flutter_tools/templates/app_shared/analysis_options.yaml.tmpl
+++ b/packages/flutter_tools/templates/app_shared/analysis_options.yaml.tmpl
@@ -16,8 +16,7 @@
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
- # and their documentation is published at
- # https://dart-lang.github.io/linter/lints/index.html.
+ # and their documentation is published at https://dart.dev/lints.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
diff --git a/packages/flutter_tools/templates/app_shared/ios.tmpl/Runner/Info.plist.tmpl b/packages/flutter_tools/templates/app_shared/ios.tmpl/Runner/Info.plist.tmpl
index 3d4696c..bb6ce2f 100644
--- a/packages/flutter_tools/templates/app_shared/ios.tmpl/Runner/Info.plist.tmpl
+++ b/packages/flutter_tools/templates/app_shared/ios.tmpl/Runner/Info.plist.tmpl
@@ -41,8 +41,6 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
- <key>UIViewControllerBasedStatusBarAppearance</key>
- <false/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
diff --git a/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Info.plist.tmpl b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Info.plist.tmpl
index 5c9b912..a4388ef 100644
--- a/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Info.plist.tmpl
+++ b/packages/flutter_tools/templates/module/ios/host_app_ephemeral/Runner.tmpl/Info.plist.tmpl
@@ -41,8 +41,6 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
- <key>UIViewControllerBasedStatusBarAppearance</key>
- <false/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
diff --git a/packages/flutter_tools/templates/plugin/android-kotlin.tmpl/src/main/kotlin/androidIdentifier/pluginClass.kt.tmpl b/packages/flutter_tools/templates/plugin/android-kotlin.tmpl/src/main/kotlin/androidIdentifier/pluginClass.kt.tmpl
index efab097..3281a43 100644
--- a/packages/flutter_tools/templates/plugin/android-kotlin.tmpl/src/main/kotlin/androidIdentifier/pluginClass.kt.tmpl
+++ b/packages/flutter_tools/templates/plugin/android-kotlin.tmpl/src/main/kotlin/androidIdentifier/pluginClass.kt.tmpl
@@ -16,12 +16,12 @@
/// when the Flutter Engine is detached from the Activity
private lateinit var channel : MethodChannel
- override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
+ override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
channel = MethodChannel(flutterPluginBinding.binaryMessenger, "{{projectName}}")
channel.setMethodCallHandler(this)
}
- override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
+ override fun onMethodCall(call: MethodCall, result: Result) {
if (call.method == "getPlatformVersion") {
result.success("Android ${android.os.Build.VERSION.RELEASE}")
} else {
@@ -29,7 +29,7 @@
}
}
- override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
+ override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
channel.setMethodCallHandler(null)
}
}
diff --git a/packages/flutter_tools/templates/skeleton/lib/src/app.dart.tmpl b/packages/flutter_tools/templates/skeleton/lib/src/app.dart.tmpl
index 6f7ad23..7ba2c2f 100644
--- a/packages/flutter_tools/templates/skeleton/lib/src/app.dart.tmpl
+++ b/packages/flutter_tools/templates/skeleton/lib/src/app.dart.tmpl
@@ -20,10 +20,10 @@
Widget build(BuildContext context) {
// Glue the SettingsController to the MaterialApp.
//
- // The AnimatedBuilder Widget listens to the SettingsController for changes.
+ // The ListenableBuilder Widget listens to the SettingsController for changes.
// Whenever the user updates their settings, the MaterialApp is rebuilt.
- return AnimatedBuilder(
- animation: settingsController,
+ return ListenableBuilder(
+ listenable: settingsController,
builder: (BuildContext context, Widget? child) {
return MaterialApp(
// Providing a restorationScopeId allows the Navigator built by the
diff --git a/packages/flutter_tools/test/commands.shard/hermetic/attach_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/attach_test.dart
index 1b3b961..dd2de79 100644
--- a/packages/flutter_tools/test/commands.shard/hermetic/attach_test.dart
+++ b/packages/flutter_tools/test/commands.shard/hermetic/attach_test.dart
@@ -105,7 +105,6 @@
testUsingContext('succeeds with iOS device with protocol discovery', () async {
final FakeIOSDevice device = FakeIOSDevice(
- logReader: fakeLogReader,
portForwarder: portForwarder,
majorSdkVersion: 12,
onGetLogReader: () {
@@ -167,7 +166,6 @@
testUsingContext('succeeds with iOS device with mDNS', () async {
final FakeIOSDevice device = FakeIOSDevice(
- logReader: fakeLogReader,
portForwarder: portForwarder,
majorSdkVersion: 16,
onGetLogReader: () {
@@ -237,7 +235,6 @@
testUsingContext('succeeds with iOS device with mDNS wireless device', () async {
final FakeIOSDevice device = FakeIOSDevice(
- logReader: fakeLogReader,
portForwarder: portForwarder,
majorSdkVersion: 16,
connectionInterface: DeviceConnectionInterface.wireless,
@@ -309,7 +306,6 @@
testUsingContext('succeeds with iOS device with mDNS wireless device with debug-port', () async {
final FakeIOSDevice device = FakeIOSDevice(
- logReader: fakeLogReader,
portForwarder: portForwarder,
majorSdkVersion: 16,
connectionInterface: DeviceConnectionInterface.wireless,
@@ -385,7 +381,6 @@
testUsingContext('succeeds with iOS device with mDNS wireless device with debug-url', () async {
final FakeIOSDevice device = FakeIOSDevice(
- logReader: fakeLogReader,
portForwarder: portForwarder,
majorSdkVersion: 16,
connectionInterface: DeviceConnectionInterface.wireless,
@@ -619,7 +614,6 @@
testUsingContext('succeeds when ipv6 is specified and debug-port is not on iOS device', () async {
final FakeIOSDevice device = FakeIOSDevice(
- logReader: fakeLogReader,
portForwarder: portForwarder,
majorSdkVersion: 12,
onGetLogReader: () {
@@ -1350,11 +1344,10 @@
class FakeIOSDevice extends Fake implements IOSDevice {
FakeIOSDevice({
DevicePortForwarder? portForwarder,
- DeviceLogReader? logReader,
this.onGetLogReader,
this.connectionInterface = DeviceConnectionInterface.attached,
this.majorSdkVersion = 0,
- }) : _portForwarder = portForwarder, _logReader = logReader;
+ }) : _portForwarder = portForwarder;
final DevicePortForwarder? _portForwarder;
@override
@@ -1373,9 +1366,6 @@
@override
DartDevelopmentService get dds => throw UnimplementedError('getter dds not implemented');
- final DeviceLogReader? _logReader;
- DeviceLogReader get logReader => _logReader!;
-
final DeviceLogReader Function()? onGetLogReader;
@override
@@ -1470,11 +1460,9 @@
}
class TestDeviceManager extends DeviceManager {
- TestDeviceManager({required this.logger}) : super(logger: logger);
+ TestDeviceManager({required super.logger});
List<Device> devices = <Device>[];
- final BufferLogger logger;
-
@override
List<DeviceDiscovery> get deviceDiscoverers {
final FakePollingDeviceDiscovery discoverer = FakePollingDeviceDiscovery();
diff --git a/packages/flutter_tools/test/commands.shard/hermetic/build_ios_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/build_ios_test.dart
index aaf9581..c1f2dc3 100644
--- a/packages/flutter_tools/test/commands.shard/hermetic/build_ios_test.dart
+++ b/packages/flutter_tools/test/commands.shard/hermetic/build_ios_test.dart
@@ -117,7 +117,7 @@
'xcresulttool',
'get',
'--path',
- _xcBundleFilePath,
+ _xcBundleDirectoryPath,
'--format',
'json',
],
@@ -173,7 +173,7 @@
'-destination',
'generic/platform=iOS',
],
- '-resultBundlePath', _xcBundleFilePath,
+ '-resultBundlePath', _xcBundleDirectoryPath,
'-resultBundleVersion', '3',
'FLUTTER_SUPPRESS_ANALYTICS=true',
'COMPILER_INDEX_STORE_ENABLE=NO',
@@ -461,7 +461,7 @@
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
xattrCommand,
setUpFakeXcodeBuildHandler(exitCode: 1, onRun: () {
- fileSystem.systemTempDirectory.childDirectory(_xcBundleFilePath).createSync();
+ fileSystem.systemTempDirectory.childDirectory(_xcBundleDirectoryPath).createSync();
}),
setUpXCResultCommand(),
setUpRsyncCommand(),
@@ -495,7 +495,7 @@
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
xattrCommand,
setUpFakeXcodeBuildHandler(exitCode: 1, onRun: () {
- fileSystem.systemTempDirectory.childDirectory(_xcBundleFilePath).createSync();
+ fileSystem.systemTempDirectory.childDirectory(_xcBundleDirectoryPath).createSync();
}, stdout: 'Lots of spew from Xcode',
),
setUpXCResultCommand(stdout: kSampleResultJsonWithIssues),
@@ -530,7 +530,7 @@
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
xattrCommand,
setUpFakeXcodeBuildHandler(exitCode: 1, onRun: () {
- fileSystem.systemTempDirectory.childDirectory(_xcBundleFilePath).createSync();
+ fileSystem.systemTempDirectory.childDirectory(_xcBundleDirectoryPath).createSync();
}),
setUpXCResultCommand(stdout: kSampleResultJsonWithIssuesToBeDiscarded),
setUpRsyncCommand(),
@@ -594,7 +594,7 @@
ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
xattrCommand,
setUpFakeXcodeBuildHandler(exitCode: 1, onRun: () {
- fileSystem.systemTempDirectory.childDirectory(_xcBundleFilePath).createSync();
+ fileSystem.systemTempDirectory.childDirectory(_xcBundleDirectoryPath).createSync();
}),
setUpXCResultCommand(stdout: kSampleResultJsonWithProvisionIssue),
setUpRsyncCommand(),
@@ -628,7 +628,7 @@
setUpFakeXcodeBuildHandler(
exitCode: 1,
onRun: () {
- fileSystem.systemTempDirectory.childDirectory(_xcBundleFilePath).createSync();
+ fileSystem.systemTempDirectory.childDirectory(_xcBundleDirectoryPath).createSync();
}
),
setUpXCResultCommand(stdout: kSampleResultJsonWithNoProvisioningProfileIssue),
@@ -661,17 +661,17 @@
exitCode: 1,
stdout: '$kConcurrentRunFailureMessage1 $kConcurrentRunFailureMessage2',
onRun: () {
- fileSystem.systemTempDirectory.childFile(_xcBundleFilePath).createSync();
+ fileSystem.systemTempDirectory.childDirectory(_xcBundleDirectoryPath).childFile('result.xcresult').createSync(recursive: true);
}
),
// The second xcodebuild is triggered due to above concurrent run failure message.
setUpFakeXcodeBuildHandler(
onRun: () {
// If the file is not cleaned, throw an error, test failure.
- if (fileSystem.systemTempDirectory.childFile(_xcBundleFilePath).existsSync()) {
+ if (fileSystem.systemTempDirectory.childDirectory(_xcBundleDirectoryPath).existsSync()) {
throwToolExit('xcresult bundle file existed.', exitCode: 2);
}
- fileSystem.systemTempDirectory.childFile(_xcBundleFilePath).createSync();
+ fileSystem.systemTempDirectory.childDirectory(_xcBundleDirectoryPath).childFile('result.xcresult').createSync(recursive: true);
}
),
setUpXCResultCommand(stdout: kSampleResultJsonNoIssues),
@@ -709,7 +709,7 @@
Runner requires a provisioning profile. Select a provisioning profile in the Signing & Capabilities editor
''',
onRun: () {
- fileSystem.systemTempDirectory.childDirectory(_xcBundleFilePath).createSync();
+ fileSystem.systemTempDirectory.childDirectory(_xcBundleDirectoryPath).createSync();
}
),
setUpXCResultCommand(stdout: kSampleResultJsonInvalidIssuesMap),
@@ -743,7 +743,7 @@
setUpFakeXcodeBuildHandler(
exitCode: 1,
onRun: () {
- fileSystem.systemTempDirectory.childDirectory(_xcBundleFilePath).createSync();
+ fileSystem.systemTempDirectory.childDirectory(_xcBundleDirectoryPath).createSync();
}
),
setUpXCResultCommand(stdout: kSampleResultJsonInvalidIssuesMap),
@@ -780,7 +780,7 @@
Runner requires a provisioning profile. Select a provisioning profile in the Signing & Capabilities editor
''',
onRun: () {
- fileSystem.systemTempDirectory.childDirectory(_xcBundleFilePath).createSync();
+ fileSystem.systemTempDirectory.childDirectory(_xcBundleDirectoryPath).createSync();
}
),
setUpXCResultCommand(stdout: kSampleResultJsonNoIssues),
@@ -815,7 +815,7 @@
setUpFakeXcodeBuildHandler(
exitCode: 1,
onRun: () {
- fileSystem.systemTempDirectory.childDirectory(_xcBundleFilePath).createSync();
+ fileSystem.systemTempDirectory.childDirectory(_xcBundleDirectoryPath).createSync();
}
),
setUpXCResultCommand(stdout: kSampleResultJsonInvalidIssuesMap),
@@ -850,7 +850,7 @@
setUpFakeXcodeBuildHandler(
exitCode: 1,
onRun: () {
- fileSystem.systemTempDirectory.childDirectory(_xcBundleFilePath).createSync();
+ fileSystem.systemTempDirectory.childDirectory(_xcBundleDirectoryPath).createSync();
}
),
setUpXCResultCommand(stdout: kSampleResultJsonWithNoProvisioningProfileIssue),
@@ -885,7 +885,7 @@
setUpFakeXcodeBuildHandler(
exitCode: 1,
onRun: () {
- fileSystem.systemTempDirectory.childDirectory(_xcBundleFilePath).createSync();
+ fileSystem.systemTempDirectory.childDirectory(_xcBundleDirectoryPath).createSync();
}
),
setUpXCResultCommand(stdout: kSampleResultJsonWithProvisionIssue),
@@ -922,7 +922,7 @@
simulator: true,
exitCode: 1,
onRun: () {
- fileSystem.systemTempDirectory.childDirectory(_xcBundleFilePath).createSync();
+ fileSystem.systemTempDirectory.childDirectory(_xcBundleDirectoryPath).createSync();
},
),
setUpXCResultCommand(),
@@ -958,7 +958,7 @@
simulator: true,
exitCode: 1,
onRun: () {
- fileSystem.systemTempDirectory.childDirectory(_xcBundleFilePath).createSync();
+ fileSystem.systemTempDirectory.childDirectory(_xcBundleDirectoryPath).createSync();
},
),
setUpXCResultCommand(stdout: kSampleResultJsonWithIssues),
@@ -996,7 +996,7 @@
simulator: true,
exitCode: 1,
onRun: () {
- fileSystem.systemTempDirectory.childDirectory(_xcBundleFilePath).createSync();
+ fileSystem.systemTempDirectory.childDirectory(_xcBundleDirectoryPath).createSync();
},
),
setUpXCResultCommand(stdout: kSampleResultJsonWithIssuesToBeDiscarded),
@@ -1040,7 +1040,7 @@
});
}
-const String _xcBundleFilePath = '/.tmp_rand0/flutter_ios_build_temp_dirrand0/temporary_xcresult_bundle';
+const String _xcBundleDirectoryPath = '/.tmp_rand0/flutter_ios_build_temp_dirrand0/temporary_xcresult_bundle';
class FakeAndroidSdk extends Fake implements AndroidSdk {
@override
diff --git a/packages/flutter_tools/test/commands.shard/hermetic/create_usage_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/create_usage_test.dart
index 82491ed..088caf9 100644
--- a/packages/flutter_tools/test/commands.shard/hermetic/create_usage_test.dart
+++ b/packages/flutter_tools/test/commands.shard/hermetic/create_usage_test.dart
@@ -19,9 +19,7 @@
import '../../src/testbed.dart';
class FakePub extends Fake implements Pub {
- FakePub(this.fs);
- final FileSystem fs;
int calledGetOffline = 0;
int calledOnline = 0;
@@ -59,7 +57,7 @@
setUp(() {
testbed = Testbed(setup: () {
- fakePub = FakePub(globals.fs);
+ fakePub = FakePub();
Cache.flutterRoot = 'flutter';
final List<String> filePaths = <String>[
globals.fs.path.join('flutter', 'packages', 'flutter', 'pubspec.yaml'),
diff --git a/packages/flutter_tools/test/commands.shard/hermetic/doctor_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/doctor_test.dart
index cd569c5..9d42023 100644
--- a/packages/flutter_tools/test/commands.shard/hermetic/doctor_test.dart
+++ b/packages/flutter_tools/test/commands.shard/hermetic/doctor_test.dart
@@ -4,7 +4,6 @@
import 'dart:async';
-import 'package:args/command_runner.dart';
import 'package:fake_async/fake_async.dart';
import 'package:file/memory.dart';
import 'package:flutter_tools/src/android/android_studio_validator.dart';
@@ -16,7 +15,6 @@
import 'package:flutter_tools/src/base/user_messages.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/cache.dart';
-import 'package:flutter_tools/src/commands/doctor.dart';
import 'package:flutter_tools/src/custom_devices/custom_device_workflow.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/doctor.dart';
@@ -32,17 +30,16 @@
import '../../src/common.dart';
import '../../src/context.dart';
import '../../src/fakes.dart';
-import '../../src/test_flutter_command_runner.dart';
void main() {
- late FakeFlutterVersion flutterVersion;
late BufferLogger logger;
late FakeProcessManager fakeProcessManager;
+ late MemoryFileSystem fs;
setUp(() {
- flutterVersion = FakeFlutterVersion();
logger = BufferLogger.test();
fakeProcessManager = FakeProcessManager.empty();
+ fs = MemoryFileSystem.test();
});
testWithoutContext('ValidationMessage equality and hashCode includes contextUrl', () {
@@ -761,27 +758,55 @@
contains(isA<CustomDeviceWorkflow>()),
);
}, overrides: <Type, Generator>{
- FileSystem: () => MemoryFileSystem.test(),
+ FileSystem: () => fs,
ProcessManager: () => fakeProcessManager,
});
- testUsingContext('Fetches tags to get the right version', () async {
- Cache.disableLocking();
+ group('FlutterValidator', () {
+ late FakeFlutterVersion initialVersion;
+ late FakeFlutterVersion secondVersion;
+ late TestFeatureFlags featureFlags;
- final DoctorCommand doctorCommand = DoctorCommand();
- final CommandRunner<void> commandRunner = createTestCommandRunner(doctorCommand);
+ setUp(() {
+ secondVersion = FakeFlutterVersion(frameworkRevisionShort: '222');
+ initialVersion = FakeFlutterVersion(
+ frameworkRevisionShort: '111',
+ nextFlutterVersion: secondVersion,
+ );
+ featureFlags = TestFeatureFlags();
+ });
- await commandRunner.run(<String>['doctor']);
-
- expect(flutterVersion.didFetchTagsAndUpdate, true);
- Cache.enableLocking();
- }, overrides: <Type, Generator>{
- ProcessManager: () => FakeProcessManager.any(),
- FileSystem: () => MemoryFileSystem.test(),
- FlutterVersion: () => flutterVersion,
- Doctor: () => NoOpDoctor(),
- }, initializeFlutterRoot: false);
-
+ testUsingContext('FlutterValidator fetches tags and gets fresh version', () async {
+ final Directory devtoolsDir = fs.directory('/path/to/flutter/bin/cache/dart-sdk/bin/resources/devtools')
+ ..createSync(recursive: true);
+ fs.directory('/path/to/flutter/bin/cache/artifacts').createSync(recursive: true);
+ devtoolsDir.childFile('version.json').writeAsStringSync('{"version": "123"}');
+ fakeProcessManager.addCommands(const <FakeCommand>[
+ FakeCommand(command: <String>['which', 'java']),
+ ]);
+ final List<DoctorValidator> validators = DoctorValidatorsProvider.test(
+ featureFlags: featureFlags,
+ platform: FakePlatform(),
+ ).validators;
+ final FlutterValidator flutterValidator = validators.whereType<FlutterValidator>().first;
+ final ValidationResult result = await flutterValidator.validate();
+ expect(
+ result.messages.map((ValidationMessage msg) => msg.message),
+ contains(contains('Framework revision 222')),
+ );
+ }, overrides: <Type, Generator>{
+ Cache: () => Cache.test(
+ rootOverride: fs.directory('/path/to/flutter'),
+ fileSystem: fs,
+ processManager: fakeProcessManager,
+ ),
+ FileSystem: () => fs,
+ FlutterVersion: () => initialVersion,
+ Platform: () => FakePlatform(),
+ ProcessManager: () => fakeProcessManager,
+ TestFeatureFlags: () => featureFlags,
+ });
+ });
testUsingContext('If android workflow is disabled, AndroidStudio validator is not included', () {
final DoctorValidatorsProvider provider = DoctorValidatorsProvider.test(
featureFlags: TestFeatureFlags(isAndroidEnabled: false),
@@ -806,41 +831,6 @@
final bool appliesToHostPlatform;
}
-
-class NoOpDoctor implements Doctor {
- @override
- bool get canLaunchAnything => true;
-
- @override
- bool get canListAnything => true;
-
- @override
- Future<bool> checkRemoteArtifacts(String engineRevision) async => true;
-
- @override
- Future<bool> diagnose({
- bool androidLicenses = false,
- bool verbose = true,
- bool showColor = true,
- AndroidLicenseValidator? androidLicenseValidator,
- bool showPii = true,
- List<ValidatorTask>? startedValidatorTasks,
- bool sendEvent = true,
- }) async => true;
-
- @override
- List<ValidatorTask> startValidatorTasks() => <ValidatorTask>[];
-
- @override
- Future<void> summary() async { }
-
- @override
- List<DoctorValidator> get validators => <DoctorValidator>[];
-
- @override
- List<Workflow> get workflows => <Workflow>[];
-}
-
class PassingValidator extends DoctorValidator {
PassingValidator(super.title);
diff --git a/packages/flutter_tools/test/commands.shard/hermetic/generate_localizations_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/generate_localizations_test.dart
index 552dd37..e2556a6 100644
--- a/packages/flutter_tools/test/commands.shard/hermetic/generate_localizations_test.dart
+++ b/packages/flutter_tools/test/commands.shard/hermetic/generate_localizations_test.dart
@@ -78,6 +78,11 @@
"description": "Sample description"
}
}''');
+ fileSystem
+ .file('pubspec.yaml')
+ .writeAsStringSync('''
+flutter:
+ generate: true''');
final GenerateLocalizationsCommand command = GenerateLocalizationsCommand(
fileSystem: fileSystem,
@@ -109,7 +114,11 @@
}
}''');
fileSystem.file('header.txt').writeAsStringSync('a header file');
-
+ fileSystem
+ .file('pubspec.yaml')
+ .writeAsStringSync('''
+flutter:
+ generate: true''');
final GenerateLocalizationsCommand command = GenerateLocalizationsCommand(
fileSystem: fileSystem,
logger: logger,
@@ -442,7 +451,7 @@
ProcessManager: () => FakeProcessManager.any(),
});
- testUsingContext('throw when generate: false and uses synthetic package when run via commandline options', () async {
+ testUsingContext('throw when generate: false and uses synthetic package when run via commandline options', () async {
final File arbFile = fileSystem.file(fileSystem.path.join('lib', 'l10n', 'app_en.arb'))
..createSync(recursive: true);
arbFile.writeAsStringSync('''
@@ -475,9 +484,21 @@
() async => createTestCommandRunner(command).run(<String>['gen-l10n', '--synthetic-package']),
throwsToolExit(message: 'Attempted to generate localizations code without having the flutter: generate flag turned on.')
);
-
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.any(),
});
+
+ testUsingContext('throws error when unexpected positional argument is provided', () {
+ final GenerateLocalizationsCommand command = GenerateLocalizationsCommand(
+ fileSystem: fileSystem,
+ logger: logger,
+ artifacts: artifacts,
+ processManager: processManager,
+ );
+ expect(
+ () async => createTestCommandRunner(command).run(<String>['gen-l10n', '--synthetic-package', 'false']),
+ throwsToolExit(message: 'Unexpected positional argument "false".')
+ );
+ });
}
diff --git a/packages/flutter_tools/test/commands.shard/hermetic/run_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/run_test.dart
index 5ccba77..ca7564e 100644
--- a/packages/flutter_tools/test/commands.shard/hermetic/run_test.dart
+++ b/packages/flutter_tools/test/commands.shard/hermetic/run_test.dart
@@ -1148,11 +1148,9 @@
}
class TestDeviceManager extends DeviceManager {
- TestDeviceManager({required this.logger}) : super(logger: logger);
+ TestDeviceManager({required super.logger});
List<Device> devices = <Device>[];
- final Logger logger;
-
@override
List<DeviceDiscovery> get deviceDiscoverers {
final FakePollingDeviceDiscovery discoverer = FakePollingDeviceDiscovery();
diff --git a/packages/flutter_tools/test/commands.shard/hermetic/symbolize_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/symbolize_test.dart
index fb5d181..44096a7 100644
--- a/packages/flutter_tools/test/commands.shard/hermetic/symbolize_test.dart
+++ b/packages/flutter_tools/test/commands.shard/hermetic/symbolize_test.dart
@@ -39,7 +39,7 @@
unawaited(symbolizationService.decode(
input: Stream<Uint8List>.fromIterable(<Uint8List>[
- utf8.encode('Hello, World\n') as Uint8List,
+ const Utf8Encoder().convert('Hello, World\n'),
]),
symbols: Uint8List(0),
output: IOSink(output.sink),
diff --git a/packages/flutter_tools/test/commands.shard/hermetic/update_packages_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/update_packages_test.dart
index 971afe7..7e75ca9 100644
--- a/packages/flutter_tools/test/commands.shard/hermetic/update_packages_test.dart
+++ b/packages/flutter_tools/test/commands.shard/hermetic/update_packages_test.dart
@@ -197,6 +197,73 @@
Logger: () => logger,
});
+ testUsingContext('--cherry-pick-package', () async {
+ final UpdatePackagesCommand command = UpdatePackagesCommand();
+ await createTestCommandRunner(command).run(<String>[
+ 'update-packages',
+ '--cherry-pick-package=vector_math',
+ '--cherry-pick-version=2.0.9',
+ ]);
+ expect(pub.pubGetDirectories, equals(<String>[
+ '/.tmp_rand0/flutter_update_packages.rand0/synthetic_package',
+ '/flutter/examples',
+ '/flutter/packages/flutter',
+ ]));
+ expect(pub.pubBatchDirectories, equals(<String>[
+ '/.tmp_rand0/flutter_update_packages.rand0/synthetic_package',
+ ]));
+ expect(pub.pubspecYamls, hasLength(3));
+ final String output = pub.pubspecYamls.first;
+ expect(output, isNotNull);
+ expect(output, contains('collection: 1.14.11\n'));
+ expect(output, contains('meta: 1.1.8\n'));
+ expect(output, contains('typed_data: 1.1.6\n'));
+ expect(output, contains('vector_math: 2.0.9\n'));
+ expect(output, isNot(contains('vector_math: 2.0.8')));
+ expect(output, isNot(contains('vector_math: ">= 2.0.8"')));
+ expect(output, isNot(contains("vector_math: '>= 2.0.8'")));
+ }, overrides: <Type, Generator>{
+ Pub: () => pub,
+ FileSystem: () => fileSystem,
+ ProcessManager: () => processManager,
+ Cache: () => Cache.test(
+ processManager: processManager,
+ ),
+ Logger: () => logger,
+ });
+
+ testUsingContext('--force-upgrade', () async {
+ final UpdatePackagesCommand command = UpdatePackagesCommand();
+ await createTestCommandRunner(command).run(<String>[
+ 'update-packages',
+ '--force-upgrade',
+ ]);
+ expect(pub.pubGetDirectories, equals(<String>[
+ '/.tmp_rand0/flutter_update_packages.rand0/synthetic_package',
+ '/flutter/examples',
+ '/flutter/packages/flutter',
+ ]));
+ expect(pub.pubBatchDirectories, equals(<String>[
+ '/.tmp_rand0/flutter_update_packages.rand0/synthetic_package',
+ ]));
+ expect(pub.pubspecYamls, hasLength(3));
+ final String output = pub.pubspecYamls.first;
+ expect(output, isNotNull);
+ expect(output, contains("collection: '>= 1.14.11'\n"));
+ expect(output, contains("meta: '>= 1.1.8'\n"));
+ expect(output, contains("typed_data: '>= 1.1.6'\n"));
+ expect(output, contains("vector_math: '>= 2.0.8'\n"));
+ expect(output, isNot(contains('vector_math: 2.0.8')));
+ }, overrides: <Type, Generator>{
+ Pub: () => pub,
+ FileSystem: () => fileSystem,
+ ProcessManager: () => processManager,
+ Cache: () => Cache.test(
+ processManager: processManager,
+ ),
+ Logger: () => logger,
+ });
+
testUsingContext('force updates packages --synthetic-package-path', () async {
final UpdatePackagesCommand command = UpdatePackagesCommand();
const String dir = '/path/to/synthetic/package';
@@ -272,6 +339,7 @@
final FileSystem fileSystem;
final List<String> pubGetDirectories = <String>[];
final List<String> pubBatchDirectories = <String>[];
+ final List<String> pubspecYamls = <String>[];
@override
Future<void> get({
@@ -287,6 +355,7 @@
PubOutputMode outputMode = PubOutputMode.all,
}) async {
pubGetDirectories.add(project.directory.path);
+ pubspecYamls.add(project.directory.childFile('pubspec.yaml').readAsStringSync());
project.directory.childFile('pubspec.lock')
..createSync(recursive: true)
..writeAsStringSync('''
diff --git a/packages/flutter_tools/test/commands.shard/permeable/build_bundle_test.dart b/packages/flutter_tools/test/commands.shard/permeable/build_bundle_test.dart
index db99b2b..c4a5018 100644
--- a/packages/flutter_tools/test/commands.shard/permeable/build_bundle_test.dart
+++ b/packages/flutter_tools/test/commands.shard/permeable/build_bundle_test.dart
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+import 'dart:typed_data';
+
import 'package:args/command_runner.dart';
import 'package:file/memory.dart';
import 'package:flutter_tools/src/base/file_system.dart';
@@ -12,6 +14,7 @@
import 'package:flutter_tools/src/bundle_builder.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/commands/build_bundle.dart';
+import 'package:flutter_tools/src/convert.dart';
import 'package:flutter_tools/src/features.dart';
import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:flutter_tools/src/project.dart';
@@ -504,7 +507,7 @@
ProcessManager: () => FakeProcessManager.any(),
});
- testUsingContext('test --dart-define-from-file option', () async {
+ testUsingContext('--dart-define-from-file successfully forwards values to build env', () async {
globals.fs.file(globals.fs.path.join('lib', 'main.dart')).createSync(recursive: true);
globals.fs.file('pubspec.yaml').createSync();
globals.fs.file('.packages').createSync();
@@ -514,7 +517,9 @@
"kInt": 1,
"kDouble": 1.1,
"name": "denghaizhu",
- "title": "this is title from config json file"
+ "title": "this is title from config json file",
+ "nullValue": null,
+ "containEqual": "sfadsfv=432f"
}
'''
);
@@ -537,12 +542,172 @@
]);
}, overrides: <Type, Generator>{
BuildSystem: () => TestBuildSystem.all(BuildResult(success: true), (Target target, Environment environment) {
- expect(environment.defines[kDartDefines], 'a0ludD0x,a0RvdWJsZT0xLjE=,bmFtZT1kZW5naGFpemh1,dGl0bGU9dGhpcyBpcyB0aXRsZSBmcm9tIGNvbmZpZyBqc29uIGZpbGU=,Ym9keT10aGlzIGlzIGJvZHkgZnJvbSBjb25maWcganNvbiBmaWxl');
+ expect(
+ _decodeDartDefines(environment),
+ containsAllInOrder(const <String>[
+ 'kInt=1',
+ 'kDouble=1.1',
+ 'name=denghaizhu',
+ 'title=this is title from config json file',
+ 'nullValue=null',
+ 'containEqual=sfadsfv=432f',
+ 'body=this is body from config json file',
+ ]),
+ );
}),
FileSystem: fsFactory,
ProcessManager: () => FakeProcessManager.any(),
});
+ testUsingContext('--dart-define-from-file correctly parses a valid env file', () async {
+ globals.fs
+ .file(globals.fs.path.join('lib', 'main.dart'))
+ .createSync(recursive: true);
+ globals.fs.file('pubspec.yaml').createSync();
+ globals.fs.file('.packages').createSync();
+ await globals.fs.file('.env').writeAsString('''
+ # comment
+ kInt=1
+ kDouble=1.1 # should be double
+
+ name=piotrfleury
+ title=this is title from config env file
+ empty=
+
+ doubleQuotes="double quotes 'value'#=" # double quotes
+ singleQuotes='single quotes "value"#=' # single quotes
+ backQuotes=`back quotes "value" '#=` # back quotes
+
+ hashString="some-#-hash-string-value"
+
+ # Play around with spaces around the equals sign.
+ spaceBeforeEqual =value
+ spaceAroundEqual = value
+ spaceAfterEqual= value
+
+ ''');
+ await globals.fs.file('.env2').writeAsString('''
+ # second comment
+
+ body=this is body from config env file
+ ''');
+ final CommandRunner<void> runner =
+ createTestCommandRunner(BuildBundleCommand(
+ logger: BufferLogger.test(),
+ ));
+
+ await runner.run(<String>[
+ 'bundle',
+ '--no-pub',
+ '--dart-define-from-file=.env',
+ '--dart-define-from-file=.env2',
+ ]);
+ }, overrides: <Type, Generator>{
+ BuildSystem: () => TestBuildSystem.all(BuildResult(success: true),
+ (Target target, Environment environment) {
+ expect(
+ _decodeDartDefines(environment),
+ containsAllInOrder(const <String>[
+ 'kInt=1',
+ 'kDouble=1.1',
+ 'name=piotrfleury',
+ 'title=this is title from config env file',
+ 'empty=',
+ "doubleQuotes=double quotes 'value'#=",
+ 'singleQuotes=single quotes "value"#=',
+ 'backQuotes=back quotes "value" \'#=',
+ 'hashString=some-#-hash-string-value',
+ 'spaceBeforeEqual=value',
+ 'spaceAroundEqual=value',
+ 'spaceAfterEqual=value',
+ 'body=this is body from config env file'
+ ]),
+ );
+ }),
+ FileSystem: fsFactory,
+ ProcessManager: () => FakeProcessManager.any(),
+ });
+
+ testUsingContext('--dart-define-from-file option env file throws a ToolExit when .env file contains a multiline value', () async {
+ globals.fs
+ .file(globals.fs.path.join('lib', 'main.dart'))
+ .createSync(recursive: true);
+ globals.fs.file('pubspec.yaml').createSync();
+ globals.fs.file('.packages').createSync();
+ await globals.fs.file('.env').writeAsString('''
+ # single line value
+ name=piotrfleury
+
+ # multi-line value
+ multiline = """ Welcome to .env demo
+ a simple counter app with .env file support
+ for more info, check out the README.md file
+ Thanks! """ # This is the welcome message that will be displayed on the counter app
+
+ ''');
+ final CommandRunner<void> runner =
+ createTestCommandRunner(BuildBundleCommand(
+ logger: BufferLogger.test(),
+ ));
+
+ expect(() => runner.run(<String>[
+ 'bundle',
+ '--no-pub',
+ '--dart-define-from-file=.env',
+ ]), throwsToolExit(message: 'Multi-line value is not supported: multiline = """ Welcome to .env demo'));
+ }, overrides: <Type, Generator>{
+ BuildSystem: () => TestBuildSystem.all(BuildResult(success: true)),
+ FileSystem: fsFactory,
+ ProcessManager: () => FakeProcessManager.any(),
+ });
+
+ testUsingContext('--dart-define-from-file option works with mixed file formats',
+ () async {
+ globals.fs
+ .file(globals.fs.path.join('lib', 'main.dart'))
+ .createSync(recursive: true);
+ globals.fs.file('pubspec.yaml').createSync();
+ globals.fs.file('.packages').createSync();
+ await globals.fs.file('.env').writeAsString('''
+ kInt=1
+ kDouble=1.1
+ name=piotrfleury
+ title=this is title from config env file
+ ''');
+ await globals.fs.file('config.json').writeAsString('''
+ {
+ "body": "this is body from config json file"
+ }
+ ''');
+ final CommandRunner<void> runner =
+ createTestCommandRunner(BuildBundleCommand(
+ logger: BufferLogger.test(),
+ ));
+
+ await runner.run(<String>[
+ 'bundle',
+ '--no-pub',
+ '--dart-define-from-file=.env',
+ '--dart-define-from-file=config.json',
+ ]);
+ }, overrides: <Type, Generator>{
+ BuildSystem: () => TestBuildSystem.all(BuildResult(success: true),
+ (Target target, Environment environment) {
+ expect(
+ _decodeDartDefines(environment),
+ containsAllInOrder(const <String>[
+ 'kInt=1',
+ 'kDouble=1.1',
+ 'name=piotrfleury',
+ 'title=this is title from config env file',
+ 'body=this is body from config json file',
+ ]),
+ );
+ }),
+ FileSystem: fsFactory,
+ ProcessManager: () => FakeProcessManager.any(),
+ });
+
testUsingContext('test --dart-define-from-file option if conflict', () async {
globals.fs.file(globals.fs.path.join('lib', 'main.dart')).createSync(recursive: true);
globals.fs.file('pubspec.yaml').createSync();
@@ -576,7 +741,10 @@
]);
}, overrides: <Type, Generator>{
BuildSystem: () => TestBuildSystem.all(BuildResult(success: true), (Target target, Environment environment) {
- expect(environment.defines[kDartDefines], 'a0ludD0y,a0RvdWJsZT0xLjE=,bmFtZT1kZW5naGFpemh1,dGl0bGU9dGhpcyBpcyB0aXRsZSBmcm9tIGNvbmZpZyBqc29uIGZpbGU=');
+ expect(
+ _decodeDartDefines(environment),
+ containsAllInOrder(<String>['kInt=2', 'kDouble=1.1', 'name=denghaizhu', 'title=this is title from config json file']),
+ );
}),
FileSystem: fsFactory,
ProcessManager: () => FakeProcessManager.any(),
@@ -632,6 +800,15 @@
});
}
+Iterable<String> _decodeDartDefines(Environment environment) {
+ final String encodedDefines = environment.defines[kDartDefines]!;
+ const Utf8Decoder byteDecoder = Utf8Decoder();
+ return encodedDefines
+ .split(',')
+ .map<Uint8List>(base64.decode)
+ .map<String>(byteDecoder.convert);
+}
+
class FakeBundleBuilder extends Fake implements BundleBuilder {
@override
Future<void> build({
diff --git a/packages/flutter_tools/test/commands.shard/permeable/upgrade_test.dart b/packages/flutter_tools/test/commands.shard/permeable/upgrade_test.dart
index 2146ca4..cc1c8bc 100644
--- a/packages/flutter_tools/test/commands.shard/permeable/upgrade_test.dart
+++ b/packages/flutter_tools/test/commands.shard/permeable/upgrade_test.dart
@@ -37,7 +37,8 @@
setUp(() {
fakeCommandRunner = FakeUpgradeCommandRunner();
- realCommandRunner = UpgradeCommandRunner();
+ realCommandRunner = UpgradeCommandRunner()
+ ..workingDirectory = getFlutterRoot();
processManager = FakeProcessManager.empty();
fakeCommandRunner.willHaveUncommittedChanges = false;
fakePlatform = FakePlatform()..environment = Map<String, String>.unmodifiable(<String, String>{
diff --git a/packages/flutter_tools/test/general.shard/analytics_test.dart b/packages/flutter_tools/test/general.shard/analytics_test.dart
index b8bfd57..c6cdf97 100644
--- a/packages/flutter_tools/test/general.shard/analytics_test.dart
+++ b/packages/flutter_tools/test/general.shard/analytics_test.dart
@@ -41,11 +41,14 @@
group('analytics', () {
late Directory tempDir;
late Config testConfig;
+ late FileSystem fs;
+ const String flutterRoot = '/path/to/flutter';
setUp(() {
- Cache.flutterRoot = '../..';
+ Cache.flutterRoot = flutterRoot;
tempDir = globals.fs.systemTempDirectory.createTempSync('flutter_tools_analytics_test.');
testConfig = Config.test();
+ fs = MemoryFileSystem.test();
});
tearDown(() {
@@ -77,7 +80,7 @@
expect(count, 0);
}, overrides: <Type, Generator>{
- FlutterVersion: () => FlutterVersion(),
+ FlutterVersion: () => FakeFlutterVersion(),
Usage: () => Usage(
configDirOverride: tempDir.path,
logFile: tempDir.childFile('analytics.log').path,
@@ -101,7 +104,7 @@
expect(count, 0);
}, overrides: <Type, Generator>{
- FlutterVersion: () => FlutterVersion(),
+ FlutterVersion: () => FakeFlutterVersion(),
Usage: () => Usage(
configDirOverride: tempDir.path,
logFile: tempDir.childFile('analytics.log').path,
@@ -118,12 +121,12 @@
expect(globals.fs.file('test').readAsStringSync(), contains('$featuresKey: enable-web'));
}, overrides: <Type, Generator>{
- FlutterVersion: () => FlutterVersion(),
+ FlutterVersion: () => FakeFlutterVersion(),
Config: () => testConfig,
Platform: () => FakePlatform(environment: <String, String>{
'FLUTTER_ANALYTICS_LOG_FILE': 'test',
}),
- FileSystem: () => MemoryFileSystem.test(),
+ FileSystem: () => fs,
ProcessManager: () => FakeProcessManager.any(),
});
@@ -141,12 +144,12 @@
contains('$featuresKey: enable-web,enable-linux-desktop,enable-macos-desktop'),
);
}, overrides: <Type, Generator>{
- FlutterVersion: () => FlutterVersion(),
+ FlutterVersion: () => FakeFlutterVersion(),
Config: () => testConfig,
Platform: () => FakePlatform(environment: <String, String>{
'FLUTTER_ANALYTICS_LOG_FILE': 'test',
}),
- FileSystem: () => MemoryFileSystem.test(),
+ FileSystem: () => fs,
ProcessManager: () => FakeProcessManager.any(),
});
});
@@ -384,6 +387,7 @@
bool showPii = true,
List<ValidatorTask>? startedValidatorTasks,
bool sendEvent = true,
+ FlutterVersion? version,
}) async {
return diagnoseSucceeds;
}
diff --git a/packages/flutter_tools/test/general.shard/android/android_project_migration_test.dart b/packages/flutter_tools/test/general.shard/android/android_project_migration_test.dart
index a6b9cfb..8722774 100644
--- a/packages/flutter_tools/test/general.shard/android/android_project_migration_test.dart
+++ b/packages/flutter_tools/test/general.shard/android/android_project_migration_test.dart
@@ -9,9 +9,6 @@
import 'package:flutter_tools/src/android/migrations/android_studio_java_gradle_conflict_migration.dart';
import 'package:flutter_tools/src/android/migrations/top_level_gradle_build_file_migration.dart';
import 'package:flutter_tools/src/base/logger.dart';
-import 'package:flutter_tools/src/base/os.dart';
-import 'package:flutter_tools/src/base/platform.dart';
-import 'package:flutter_tools/src/base/process.dart';
import 'package:flutter_tools/src/base/version.dart';
import 'package:flutter_tools/src/project.dart';
import 'package:test/fake.dart';
@@ -287,8 +284,3 @@
throw Exception('How did this happen?');
}
}
-
-class FakeFileSystem extends Fake implements FileSystem {}
-class FakeProcessUtils extends Fake implements ProcessUtils {}
-class FakePlatform extends Fake implements Platform {}
-class FakeOperatingSystemUtils extends Fake implements OperatingSystemUtils {}
diff --git a/packages/flutter_tools/test/general.shard/android/android_sdk_test.dart b/packages/flutter_tools/test/general.shard/android/android_sdk_test.dart
index b70b343..9e7ed95 100644
--- a/packages/flutter_tools/test/general.shard/android/android_sdk_test.dart
+++ b/packages/flutter_tools/test/general.shard/android/android_sdk_test.dart
@@ -4,12 +4,10 @@
import 'package:file/memory.dart';
import 'package:flutter_tools/src/android/android_sdk.dart';
-import 'package:flutter_tools/src/android/android_studio.dart';
import 'package:flutter_tools/src/base/config.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/globals.dart' as globals;
-import 'package:test/fake.dart';
import '../../src/common.dart';
import '../../src/context.dart';
@@ -424,13 +422,3 @@
ro.build.version.sdk=24
ro.build.version.codename=REL
''';
-
-class FakeAndroidStudioWithJdk extends Fake implements AndroidStudio {
- @override
- String? get javaPath => '/fake/android_studio/java/path/';
-}
-
-class FakeAndroidStudioWithoutJdk extends Fake implements AndroidStudio {
- @override
- String? get javaPath => null;
-}
diff --git a/packages/flutter_tools/test/general.shard/android/gradle_errors_test.dart b/packages/flutter_tools/test/general.shard/android/gradle_errors_test.dart
index 498b175..28cdf71 100644
--- a/packages/flutter_tools/test/general.shard/android/gradle_errors_test.dart
+++ b/packages/flutter_tools/test/general.shard/android/gradle_errors_test.dart
@@ -51,6 +51,7 @@
zipExceptionHandler,
incompatibleJavaAndGradleVersionsHandler,
remoteTerminatedHandshakeHandler,
+ couldNotOpenCacheDirectoryHandler,
])
);
});
@@ -134,6 +135,7 @@
)
);
});
+
testUsingContext('retries if gradle fails downloading with proxy error', () async {
const String errorMessage = r'''
Exception in thread "main" java.io.IOException: Unable to tunnel through proxy. Proxy returns "HTTP/1.1 400 Bad Request"
@@ -627,9 +629,7 @@
)
);
});
- });
- group('permission errors', () {
testUsingContext('pattern', () async {
const String errorMessage = '''
Permission denied
@@ -1386,6 +1386,32 @@
ProcessManager: () => processManager,
});
});
+
+ testUsingContext('couldNotOpenCacheDirectoryHandler', () async {
+ final GradleBuildStatus status = await couldNotOpenCacheDirectoryHandler.handler(
+ line: '''
+FAILURE: Build failed with an exception.
+
+* Where:
+Script '/Volumes/Work/s/w/ir/x/w/flutter/packages/flutter_tools/gradle/src/main/groovy/flutter.groovy' line: 276
+
+* What went wrong:
+A problem occurred evaluating script.
+> Failed to apply plugin class 'FlutterPlugin'.
+ > Could not open cache directory 41rl0ui7kgmsyfwn97o2jypl6 (/Volumes/Work/s/w/ir/cache/gradle/caches/6.7/gradle-kotlin-dsl/41rl0ui7kgmsyfwn97o2jypl6).
+ > Failed to create Jar file /Volumes/Work/s/w/ir/cache/gradle/caches/6.7/generated-gradle-jars/gradle-api-6.7.jar.''',
+ project: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory),
+ usesAndroidX: true,
+ multidexEnabled: true,
+ );
+ expect(testLogger.errorText, contains('Gradle threw an error while resolving dependencies'));
+ expect(status, GradleBuildStatus.retry);
+ }, overrides: <Type, Generator>{
+ GradleUtils: () => FakeGradleUtils(),
+ Platform: () => fakePlatform('android'),
+ FileSystem: () => fileSystem,
+ ProcessManager: () => processManager,
+ });
}
bool formatTestErrorMessage(String errorMessage, GradleHandledError error) {
diff --git a/packages/flutter_tools/test/general.shard/artifact_updater_test.dart b/packages/flutter_tools/test/general.shard/artifact_updater_test.dart
index 2fc87d4..96780ec 100644
--- a/packages/flutter_tools/test/general.shard/artifact_updater_test.dart
+++ b/packages/flutter_tools/test/general.shard/artifact_updater_test.dart
@@ -371,7 +371,7 @@
});
testWithoutContext('ArtifactUpdater will de-download a file if unzipping fails on windows', () async {
- final FakeOperatingSystemUtils operatingSystemUtils = FakeOperatingSystemUtils(windows: true);
+ final FakeOperatingSystemUtils operatingSystemUtils = FakeOperatingSystemUtils();
final MemoryFileSystem fileSystem = MemoryFileSystem.test();
final BufferLogger logger = BufferLogger.test();
final ArtifactUpdater artifactUpdater = ArtifactUpdater(
@@ -421,7 +421,7 @@
});
testWithoutContext('ArtifactUpdater will bail if unzipping fails more than twice on Windows', () async {
- final FakeOperatingSystemUtils operatingSystemUtils = FakeOperatingSystemUtils(windows: true);
+ final FakeOperatingSystemUtils operatingSystemUtils = FakeOperatingSystemUtils();
final MemoryFileSystem fileSystem = MemoryFileSystem.test();
final BufferLogger logger = BufferLogger.test();
final ArtifactUpdater artifactUpdater = ArtifactUpdater(
@@ -529,10 +529,7 @@
}
class FakeOperatingSystemUtils extends Fake implements OperatingSystemUtils {
- FakeOperatingSystemUtils({this.windows = false});
-
int failures = 0;
- final bool windows;
/// A mapping of zip [file] paths to callbacks that receive the [targetDirectory].
///
diff --git a/packages/flutter_tools/test/general.shard/dap/flutter_adapter_test.dart b/packages/flutter_tools/test/general.shard/dap/flutter_adapter_test.dart
index a76b9fd..4dd3e0b 100644
--- a/packages/flutter_tools/test/general.shard/dap/flutter_adapter_test.dart
+++ b/packages/flutter_tools/test/general.shard/dap/flutter_adapter_test.dart
@@ -11,7 +11,7 @@
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/debug_adapters/flutter_adapter.dart';
import 'package:flutter_tools/src/debug_adapters/flutter_adapter_args.dart';
-import 'package:flutter_tools/src/globals.dart' as globals show platform;
+import 'package:flutter_tools/src/globals.dart' as globals show fs, platform;
import 'package:test/fake.dart';
import 'package:test/test.dart';
import 'package:vm_service/vm_service.dart';
@@ -44,7 +44,7 @@
final Completer<void> responseCompleter = Completer<void>();
final FlutterLaunchRequestArguments args = FlutterLaunchRequestArguments(
- cwd: '/project',
+ cwd: '.',
program: 'foo.dart',
);
@@ -63,7 +63,7 @@
final Completer<void> responseCompleter = Completer<void>();
final FlutterLaunchRequestArguments args = FlutterLaunchRequestArguments(
- cwd: '/project',
+ cwd: '.',
program: 'foo.dart',
env: <String, String>{
'MY_TEST_ENV': 'MY_TEST_VALUE',
@@ -85,7 +85,7 @@
final Completer<void> responseCompleter = Completer<void>();
final FlutterLaunchRequestArguments args = FlutterLaunchRequestArguments(
- cwd: '/project',
+ cwd: '.',
program: 'foo.dart',
);
@@ -112,7 +112,7 @@
);
final FlutterLaunchRequestArguments args = FlutterLaunchRequestArguments(
- cwd: '/project',
+ cwd: '.',
program: 'foo.dart',
);
@@ -146,7 +146,7 @@
);
final FlutterLaunchRequestArguments args = FlutterLaunchRequestArguments(
- cwd: '/project',
+ cwd: '.',
program: 'foo.dart',
);
@@ -170,7 +170,7 @@
);
final FlutterLaunchRequestArguments args = FlutterLaunchRequestArguments(
- cwd: '/project',
+ cwd: '.',
program: 'foo.dart',
);
@@ -195,7 +195,7 @@
final Completer<void> launchCompleter = Completer<void>();
final FlutterLaunchRequestArguments launchArgs = FlutterLaunchRequestArguments(
- cwd: '/project',
+ cwd: '.',
program: 'foo.dart',
);
final Completer<void> restartCompleter = Completer<void>();
@@ -221,7 +221,7 @@
final Completer<void> responseCompleter = Completer<void>();
final FlutterLaunchRequestArguments args = FlutterLaunchRequestArguments(
- cwd: '/project',
+ cwd: '.',
program: 'foo.dart',
);
@@ -261,7 +261,7 @@
final Completer<void> responseCompleter = Completer<void>();
final FlutterAttachRequestArguments args = FlutterAttachRequestArguments(
- cwd: '/project',
+ cwd: '.',
);
await adapter.configurationDoneRequest(MockRequest(), null, () {});
@@ -280,7 +280,7 @@
final FlutterAttachRequestArguments args =
FlutterAttachRequestArguments(
- cwd: '/project',
+ cwd: '.',
program: 'program/main.dart',
);
@@ -299,6 +299,107 @@
]));
});
+ test('runs "flutter attach" with --debug-uri if vmServiceUri is passed', () async {
+ final MockFlutterDebugAdapter adapter = MockFlutterDebugAdapter(
+ fileSystem: MemoryFileSystem.test(style: fsStyle),
+ platform: platform,
+ );
+ final Completer<void> responseCompleter = Completer<void>();
+
+ final FlutterAttachRequestArguments args =
+ FlutterAttachRequestArguments(
+ cwd: '.',
+ program: 'program/main.dart',
+ vmServiceUri: 'ws://1.2.3.4/ws'
+ );
+
+ await adapter.configurationDoneRequest(MockRequest(), null, () {});
+ await adapter.attachRequest(
+ MockRequest(), args, responseCompleter.complete);
+ await responseCompleter.future;
+
+ expect(
+ adapter.processArgs,
+ containsAllInOrder(<String>[
+ 'attach',
+ '--machine',
+ '--debug-uri',
+ 'ws://1.2.3.4/ws',
+ '--target',
+ 'program/main.dart',
+ ]));
+ });
+
+ test('runs "flutter attach" with --debug-uri if vmServiceInfoFile exists', () async {
+ final MockFlutterDebugAdapter adapter = MockFlutterDebugAdapter(
+ fileSystem: MemoryFileSystem.test(style: fsStyle),
+ platform: platform,
+ );
+ final Completer<void> responseCompleter = Completer<void>();
+ final File serviceInfoFile = globals.fs.systemTempDirectory.createTempSync('dap_flutter_attach_vmServiceInfoFile').childFile('vmServiceInfo.json');
+
+ final FlutterAttachRequestArguments args =
+ FlutterAttachRequestArguments(
+ cwd: '.',
+ program: 'program/main.dart',
+ vmServiceInfoFile: serviceInfoFile.path,
+ );
+
+ // Write the service info file before trying to attach:
+ serviceInfoFile.writeAsStringSync('{ "uri": "ws://1.2.3.4/ws" }');
+
+ await adapter.configurationDoneRequest(MockRequest(), null, () {});
+ await adapter.attachRequest(MockRequest(), args, responseCompleter.complete);
+ await responseCompleter.future;
+
+ expect(
+ adapter.processArgs,
+ containsAllInOrder(<String>[
+ 'attach',
+ '--machine',
+ '--debug-uri',
+ 'ws://1.2.3.4/ws',
+ '--target',
+ 'program/main.dart',
+ ]));
+ });
+
+ test('runs "flutter attach" with --debug-uri if vmServiceInfoFile is created later', () async {
+ final MockFlutterDebugAdapter adapter = MockFlutterDebugAdapter(
+ fileSystem: MemoryFileSystem.test(style: fsStyle),
+ platform: platform,
+ );
+ final Completer<void> responseCompleter = Completer<void>();
+ final File serviceInfoFile = globals.fs.systemTempDirectory.createTempSync('dap_flutter_attach_vmServiceInfoFile').childFile('vmServiceInfo.json');
+
+ final FlutterAttachRequestArguments args =
+ FlutterAttachRequestArguments(
+ cwd: '.',
+ program: 'program/main.dart',
+ vmServiceInfoFile: serviceInfoFile.path,
+ );
+
+
+ await adapter.configurationDoneRequest(MockRequest(), null, () {});
+ final Future<void> attachResponseFuture = adapter.attachRequest(MockRequest(), args, responseCompleter.complete);
+ // Write the service info file a little later to ensure we detect it:
+ await pumpEventQueue(times:5000);
+ serviceInfoFile.writeAsStringSync('{ "uri": "ws://1.2.3.4/ws" }');
+ await attachResponseFuture;
+ await responseCompleter.future;
+
+ expect(
+ adapter.processArgs,
+ containsAllInOrder(<String>[
+ 'attach',
+ '--machine',
+ '--debug-uri',
+ 'ws://1.2.3.4/ws',
+ '--target',
+ 'program/main.dart',
+ ]));
+ });
+
test('does not record the VMs PID for terminating', () async {
final MockFlutterDebugAdapter adapter = MockFlutterDebugAdapter(
fileSystem: MemoryFileSystem.test(style: fsStyle),
@@ -307,7 +408,7 @@
final Completer<void> responseCompleter = Completer<void>();
final FlutterAttachRequestArguments args = FlutterAttachRequestArguments(
- cwd: '/project',
+ cwd: '.',
);
await adapter.configurationDoneRequest(MockRequest(), null, () {});
@@ -329,7 +430,7 @@
);
final FlutterAttachRequestArguments args = FlutterAttachRequestArguments(
- cwd: '/project',
+ cwd: '.',
);
await adapter.configurationDoneRequest(MockRequest(), null, () {});
@@ -417,7 +518,7 @@
final Completer<void> responseCompleter = Completer<void>();
final FlutterLaunchRequestArguments args = FlutterLaunchRequestArguments(
- cwd: '/project',
+ cwd: '.',
program: 'foo.dart',
);
@@ -436,7 +537,7 @@
final Completer<void> responseCompleter = Completer<void>();
final FlutterLaunchRequestArguments args = FlutterLaunchRequestArguments(
- cwd: '/project',
+ cwd: '.',
program: 'foo.dart',
noDebug: true,
);
@@ -456,7 +557,7 @@
final Completer<void> responseCompleter = Completer<void>();
final FlutterLaunchRequestArguments args = FlutterLaunchRequestArguments(
- cwd: '/project',
+ cwd: '.',
program: 'foo.dart',
toolArgs: <String>['--profile'],
);
@@ -476,7 +577,7 @@
final Completer<void> responseCompleter = Completer<void>();
final FlutterLaunchRequestArguments args = FlutterLaunchRequestArguments(
- cwd: '/project',
+ cwd: '.',
program: 'foo.dart',
toolArgs: <String>['--release'],
);
@@ -497,7 +598,7 @@
final Completer<void> responseCompleter = Completer<void>();
final FlutterLaunchRequestArguments args = FlutterLaunchRequestArguments(
- cwd: '/project',
+ cwd: '.',
program: 'foo.dart',
toolArgs: <String>['tool_arg'],
noDebug: true,
@@ -558,7 +659,7 @@
platform: platform,
);
final FlutterLaunchRequestArguments args = FlutterLaunchRequestArguments(
- cwd: '/project',
+ cwd: '.',
program: 'foo.dart',
customTool: '/custom/flutter',
noDebug: true,
@@ -580,7 +681,7 @@
platform: platform,
);
final FlutterLaunchRequestArguments args = FlutterLaunchRequestArguments(
- cwd: '/project',
+ cwd: '.',
program: 'foo.dart',
customTool: '/custom/flutter',
customToolReplacesArgs: 9999, // replaces all built-in args
diff --git a/packages/flutter_tools/test/general.shard/dap/flutter_test_adapter_test.dart b/packages/flutter_tools/test/general.shard/dap/flutter_test_adapter_test.dart
index a2717ea..26710f2 100644
--- a/packages/flutter_tools/test/general.shard/dap/flutter_test_adapter_test.dart
+++ b/packages/flutter_tools/test/general.shard/dap/flutter_test_adapter_test.dart
@@ -37,7 +37,7 @@
final Completer<void> responseCompleter = Completer<void>();
final MockRequest request = MockRequest();
final FlutterLaunchRequestArguments args = FlutterLaunchRequestArguments(
- cwd: '/project',
+ cwd: '.',
program: 'foo.dart',
toolArgs: <String>['tool_arg'],
noDebug: true,
@@ -59,7 +59,7 @@
final Completer<void> responseCompleter = Completer<void>();
final MockRequest request = MockRequest();
final FlutterLaunchRequestArguments args = FlutterLaunchRequestArguments(
- cwd: '/project',
+ cwd: '.',
program: 'foo.dart',
env: <String, String>{
'MY_TEST_ENV': 'MY_TEST_VALUE',
@@ -82,7 +82,7 @@
final Completer<void> responseCompleter = Completer<void>();
final MockRequest request = MockRequest();
final FlutterLaunchRequestArguments args = FlutterLaunchRequestArguments(
- cwd: '/project',
+ cwd: '.',
program: 'foo.dart',
customTool: '/custom/flutter',
noDebug: true,
@@ -105,7 +105,7 @@
final Completer<void> responseCompleter = Completer<void>();
final MockRequest request = MockRequest();
final FlutterLaunchRequestArguments args = FlutterLaunchRequestArguments(
- cwd: '/project',
+ cwd: '.',
program: 'foo.dart',
customTool: '/custom/flutter',
customToolReplacesArgs: 9999, // replaces all built-in args
diff --git a/packages/flutter_tools/test/general.shard/dart/pub_get_test.dart b/packages/flutter_tools/test/general.shard/dart/pub_get_test.dart
index 1357925..5309196 100644
--- a/packages/flutter_tools/test/general.shard/dart/pub_get_test.dart
+++ b/packages/flutter_tools/test/general.shard/dart/pub_get_test.dart
@@ -940,6 +940,8 @@
context: PubContext.flutterTests);
expect(logger.statusText,
contains('Found an existing Pub cache at /global/.pub-cache'));
+ expect(logger.statusText,
+ contains('It can be reset by running `dart pub cache clean`'));
expect(
logger.statusText,
contains(
diff --git a/packages/flutter_tools/test/general.shard/flutter_platform_test.dart b/packages/flutter_tools/test/general.shard/flutter_platform_test.dart
index 89510dc..6f4b5f6 100644
--- a/packages/flutter_tools/test/general.shard/flutter_platform_test.dart
+++ b/packages/flutter_tools/test/general.shard/flutter_platform_test.dart
@@ -8,7 +8,6 @@
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/test/flutter_platform.dart';
-import 'package:test/fake.dart';
import 'package:test_core/backend.dart'; // ignore: deprecated_member_use
import '../src/common.dart';
@@ -25,6 +24,11 @@
});
group('FlutterPlatform', () {
+ late SuitePlatform fakeSuitePlatform;
+ setUp(() {
+ fakeSuitePlatform = SuitePlatform(Runtime.vm);
+ });
+
testUsingContext('ensureConfiguration throws an error if an '
'explicitVmServicePort is specified and more than one test file', () async {
final FlutterPlatform flutterPlatform = FlutterPlatform(
@@ -35,9 +39,9 @@
),
enableVmService: false,
);
- flutterPlatform.loadChannel('test1.dart', FakeSuitePlatform());
+ flutterPlatform.loadChannel('test1.dart', fakeSuitePlatform);
- expect(() => flutterPlatform.loadChannel('test2.dart', FakeSuitePlatform()), throwsToolExit());
+ expect(() => flutterPlatform.loadChannel('test2.dart', fakeSuitePlatform), throwsToolExit());
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.any(),
@@ -51,9 +55,9 @@
precompiledDillPath: 'example.dill',
enableVmService: false,
);
- flutterPlatform.loadChannel('test1.dart', FakeSuitePlatform());
+ flutterPlatform.loadChannel('test1.dart', fakeSuitePlatform);
- expect(() => flutterPlatform.loadChannel('test2.dart', FakeSuitePlatform()), throwsToolExit());
+ expect(() => flutterPlatform.loadChannel('test2.dart', fakeSuitePlatform), throwsToolExit());
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.any(),
@@ -119,5 +123,3 @@
});
});
}
-
-class FakeSuitePlatform extends Fake implements SuitePlatform { }
diff --git a/packages/flutter_tools/test/general.shard/generate_localizations_test.dart b/packages/flutter_tools/test/general.shard/generate_localizations_test.dart
index 4e6070d..67cc966 100644
--- a/packages/flutter_tools/test/general.shard/generate_localizations_test.dart
+++ b/packages/flutter_tools/test/general.shard/generate_localizations_test.dart
@@ -59,6 +59,13 @@
.writeAsStringSync(singleMessageArbFileString);
l10nDirectory.childFile(esArbFileName)
.writeAsStringSync(singleEsMessageArbFileString);
+ fs.file('pubspec.yaml')
+ ..createSync(recursive: true)
+ ..writeAsStringSync('''
+flutter:
+ generate: true
+''');
+
}
void main() {
@@ -70,6 +77,67 @@
late String syntheticPackagePath;
late String syntheticL10nPackagePath;
+ LocalizationsGenerator setupLocalizations(
+ Map<String, String> localeToArbFile,
+ {
+ String? yamlFile,
+ String? outputPathString,
+ String? outputFileString,
+ String? headerString,
+ String? headerFile,
+ String? untranslatedMessagesFile,
+ bool useSyntheticPackage = true,
+ bool isFromYaml = false,
+ bool usesNullableGetter = true,
+ String? inputsAndOutputsListPath,
+ List<String>? preferredSupportedLocales,
+ bool useDeferredLoading = false,
+ bool useEscaping = false,
+ bool areResourceAttributeRequired = false,
+ bool suppressWarnings = false,
+ void Function(Directory)? setup,
+ }
+ ) {
+ final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
+ ..createSync(recursive: true);
+ for (final String locale in localeToArbFile.keys) {
+ l10nDirectory.childFile('app_$locale.arb')
+ .writeAsStringSync(localeToArbFile[locale]!);
+ }
+ if (setup != null) {
+ setup(l10nDirectory);
+ }
+ return LocalizationsGenerator(
+ fileSystem: fs,
+ inputPathString: l10nDirectory.path,
+ outputPathString: outputPathString ?? l10nDirectory.path,
+ templateArbFileName: defaultTemplateArbFileName,
+ outputFileString: outputFileString ?? defaultOutputFileString,
+ classNameString: defaultClassNameString,
+ headerString: headerString,
+ headerFile: headerFile,
+ logger: logger,
+ untranslatedMessagesFile: untranslatedMessagesFile,
+ useSyntheticPackage: useSyntheticPackage,
+ inputsAndOutputsListPath: inputsAndOutputsListPath,
+ usesNullableGetter: usesNullableGetter,
+ preferredSupportedLocales: preferredSupportedLocales,
+ useDeferredLoading: useDeferredLoading,
+ useEscaping: useEscaping,
+ areResourceAttributesRequired: areResourceAttributeRequired,
+ suppressWarnings: suppressWarnings,
+ )
+ ..loadResources()
+ ..writeOutputFiles(isFromYaml: isFromYaml);
+ }
+
+ String getGeneratedFileContent({String? locale}) {
+ final String fileName = locale == null ? 'output-localization-file.dart' : 'output-localization-file_$locale.dart';
+ return fs.file(
+ fs.path.join(syntheticL10nPackagePath, fileName)
+ ).readAsStringSync();
+ }
+
setUp(() {
fs = MemoryFileSystem.test();
logger = BufferLogger.test();
@@ -269,61 +337,28 @@
});
testWithoutContext('correctly adds a headerString when it is set', () {
- _standardFlutterDirectoryL10nSetup(fs);
-
- final LocalizationsGenerator generator = LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- headerString: '/// Sample header',
- logger: logger,
- );
-
+ final LocalizationsGenerator generator = setupLocalizations(<String, String>{
+ 'en': singleMessageArbFileString,
+ 'es': singleEsMessageArbFileString,
+ }, headerString: '/// Sample header');
expect(generator.header, '/// Sample header');
});
testWithoutContext('correctly adds a headerFile when it is set', () {
- fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
- ..createSync(recursive: true)
- ..childFile(defaultTemplateArbFileName).writeAsStringSync(singleMessageArbFileString)
- ..childFile(esArbFileName).writeAsStringSync(singleEsMessageArbFileString)
- ..childFile('header.txt').writeAsStringSync('/// Sample header in a text file');
-
- final LocalizationsGenerator generator = LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- headerFile: 'header.txt',
- logger: logger,
- );
-
+ final LocalizationsGenerator generator = setupLocalizations(<String, String>{
+ 'en': singleMessageArbFileString,
+ 'es': singleEsMessageArbFileString,
+ }, headerFile: 'header.txt', setup: (Directory l10nDirectory) {
+ l10nDirectory.childFile('header.txt').writeAsStringSync('/// Sample header in a text file');
+ });
expect(generator.header, '/// Sample header in a text file');
});
testWithoutContext('sets templateArbFileName with more than one underscore correctly', () {
- final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
- ..createSync(recursive: true);
- l10nDirectory.childFile('app_localizations_en.arb')
- .writeAsStringSync(singleMessageArbFileString);
- l10nDirectory.childFile('app_localizations_es.arb')
- .writeAsStringSync(singleEsMessageArbFileString);
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- templateArbFileName: 'app_localizations_en.arb',
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
-
+ setupLocalizations(<String, String>{
+ 'en': singleMessageArbFileString,
+ 'es': singleEsMessageArbFileString,
+ });
final Directory outputDirectory = fs.directory(syntheticL10nPackagePath);
expect(outputDirectory.childFile('output-localization-file.dart').existsSync(), isTrue);
expect(outputDirectory.childFile('output-localization-file_en.dart').existsSync(), isTrue);
@@ -331,22 +366,13 @@
});
testWithoutContext('filenames with invalid locales should not be recognized', () {
- final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
- ..createSync(recursive: true);
- l10nDirectory.childFile('app_localizations_en.arb')
- .writeAsStringSync(singleMessageArbFileString);
- l10nDirectory.childFile('app_localizations_en_CA_foo.arb')
- .writeAsStringSync(singleMessageArbFileString);
expect(
() {
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- templateArbFileName: 'app_localizations_en.arb',
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- ).loadResources();
+ // This attempts to create 'app_localizations_en_CA_foo.arb'.
+ setupLocalizations(<String, String>{
+ 'en': singleMessageArbFileString,
+ 'en_CA_foo': singleMessageArbFileString,
+ });
},
throwsA(isA<L10nException>().having(
(L10nException e) => e.message,
@@ -357,28 +383,12 @@
});
testWithoutContext('correctly creates an untranslated messages file (useSyntheticPackage = true)', () {
- fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
- ..createSync(recursive: true)
- ..childFile(defaultTemplateArbFileName).writeAsStringSync(twoMessageArbFileString)
- ..childFile(esArbFileName).writeAsStringSync(singleEsMessageArbFileString);
-
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- untranslatedMessagesFile: fs.path.join('lib', 'l10n', 'unimplemented_message_translations.json'),
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
-
- final File unimplementedOutputFile = fs.file(
- fs.path.join('lib', 'l10n', 'unimplemented_message_translations.json'),
- );
- final String unimplementedOutputString = unimplementedOutputFile.readAsStringSync();
+ final String untranslatedMessagesFilePath = fs.path.join('lib', 'l10n', 'unimplemented_message_translations.json');
+ setupLocalizations(<String, String>{
+ 'en': twoMessageArbFileString,
+ 'es': singleEsMessageArbFileString,
+ }, untranslatedMessagesFile: untranslatedMessagesFilePath);
+ final String unimplementedOutputString = fs.file(untranslatedMessagesFilePath).readAsStringSync();
try {
// Since ARB file is essentially JSON, decoding it should not fail.
json.decode(unimplementedOutputString);
@@ -390,29 +400,12 @@
});
testWithoutContext('correctly creates an untranslated messages file (useSyntheticPackage = false)', () {
- fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
- ..createSync(recursive: true)
- ..childFile(defaultTemplateArbFileName).writeAsStringSync(twoMessageArbFileString)
- ..childFile(esArbFileName).writeAsStringSync(singleEsMessageArbFileString);
-
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- useSyntheticPackage: false,
- untranslatedMessagesFile: fs.path.join('lib', 'l10n', 'unimplemented_message_translations.json'),
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
-
- final File unimplementedOutputFile = fs.file(
- fs.path.join('lib', 'l10n', 'unimplemented_message_translations.json'),
- );
- final String unimplementedOutputString = unimplementedOutputFile.readAsStringSync();
+ final String untranslatedMessagesFilePath = fs.path.join('lib', 'l10n', 'unimplemented_message_translations.json');
+ setupLocalizations(<String, String>{
+ 'en': twoMessageArbFileString,
+ 'es': singleMessageArbFileString,
+ }, useSyntheticPackage: false, untranslatedMessagesFile: untranslatedMessagesFilePath);
+ final String unimplementedOutputString = fs.file(untranslatedMessagesFilePath).readAsStringSync();
try {
// Since ARB file is essentially JSON, decoding it should not fail.
json.decode(unimplementedOutputString);
@@ -427,24 +420,10 @@
'untranslated messages suggestion is printed when translation is missing: '
'command line message',
() {
- fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
- ..createSync(recursive: true)
- ..childFile(defaultTemplateArbFileName).writeAsStringSync(twoMessageArbFileString)
- ..childFile(esArbFileName).writeAsStringSync(singleEsMessageArbFileString);
-
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- useSyntheticPackage: false,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
-
+ setupLocalizations(<String, String>{
+ 'en': twoMessageArbFileString,
+ 'es': singleEsMessageArbFileString,
+ });
expect(
logger.statusText,
contains('To see a detailed report, use the --untranslated-messages-file'),
@@ -460,22 +439,10 @@
'untranslated messages suggestion is printed when translation is missing: '
'l10n.yaml message',
() {
- fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
- ..createSync(recursive: true)
- ..childFile(defaultTemplateArbFileName).writeAsStringSync(twoMessageArbFileString)
- ..childFile(esArbFileName).writeAsStringSync(singleEsMessageArbFileString);
-
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles(isFromYaml: true);
-
+ setupLocalizations(<String, String>{
+ 'en': twoMessageArbFileString,
+ 'es': singleEsMessageArbFileString,
+ }, isFromYaml: true);
expect(
logger.statusText,
contains('To see a detailed report, use the untranslated-messages-file'),
@@ -491,45 +458,26 @@
'unimplemented messages suggestion is not printed when all messages '
'are fully translated',
() {
- fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
- ..createSync(recursive: true)
- ..childFile(defaultTemplateArbFileName).writeAsStringSync(twoMessageArbFileString)
- ..childFile(esArbFileName).writeAsStringSync(twoMessageArbFileString);
-
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
-
- expect(logger.statusText, '');
+ setupLocalizations(<String, String>{
+ 'en': twoMessageArbFileString,
+ 'es': twoMessageArbFileString,
+ });
+ expect(logger.statusText, equals(''));
},
);
testWithoutContext('untranslated messages file included in generated JSON list of outputs', () {
- _standardFlutterDirectoryL10nSetup(fs);
-
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
+ final String untranslatedMessagesFilePath = fs.path.join('lib', 'l10n', 'unimplemented_message_translations.json');
+ setupLocalizations(
+ <String, String>{
+ 'en': twoMessageArbFileString,
+ 'es': singleEsMessageArbFileString,
+ },
+ untranslatedMessagesFile: untranslatedMessagesFilePath,
inputsAndOutputsListPath: syntheticL10nPackagePath,
- untranslatedMessagesFile: fs.path.join('lib', 'l10n', 'unimplemented_message_translations.json'),
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
-
+ );
final File inputsAndOutputsList = fs.file(
- fs.path.join(syntheticL10nPackagePath, 'gen_l10n_inputs_and_outputs.json'),
+ fs.path.join(syntheticL10nPackagePath, 'gen_l10n_inputs_and_outputs.json')
);
expect(inputsAndOutputsList.existsSync(), isTrue);
final Map<String, dynamic> jsonResult = json.decode(
@@ -635,30 +583,18 @@
'generates nullable localizations class getter via static `of` method '
'by default',
() {
- _standardFlutterDirectoryL10nSetup(fs);
-
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: fs.path.join('lib', 'l10n', 'output'),
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- useSyntheticPackage: false,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
-
- final Directory outputDirectory = fs.directory('lib').childDirectory('l10n').childDirectory('output');
- expect(outputDirectory.existsSync(), isTrue);
- expect(outputDirectory.childFile('output-localization-file.dart').existsSync(), isTrue);
+ final LocalizationsGenerator generator = setupLocalizations(<String, String>{
+ 'en': singleMessageArbFileString,
+ 'es': singleEsMessageArbFileString,
+ });
+ expect(generator.outputDirectory.existsSync(), isTrue);
+ expect(generator.outputDirectory.childFile('output-localization-file.dart').existsSync(), isTrue);
expect(
- outputDirectory.childFile('output-localization-file.dart').readAsStringSync(),
+ generator.outputDirectory.childFile('output-localization-file.dart').readAsStringSync(),
contains('static AppLocalizations? of(BuildContext context)'),
);
expect(
- outputDirectory.childFile('output-localization-file.dart').readAsStringSync(),
+ generator.outputDirectory.childFile('output-localization-file.dart').readAsStringSync(),
contains('return Localizations.of<AppLocalizations>(context, AppLocalizations);'),
);
},
@@ -667,51 +603,28 @@
testWithoutContext(
'can generate non-nullable localizations class getter via static `of` method ',
() {
- _standardFlutterDirectoryL10nSetup(fs);
-
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: fs.path.join('lib', 'l10n', 'output'),
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- useSyntheticPackage: false,
- usesNullableGetter: false,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
-
- final Directory outputDirectory = fs.directory('lib').childDirectory('l10n').childDirectory('output');
- expect(outputDirectory.existsSync(), isTrue);
- expect(outputDirectory.childFile('output-localization-file.dart').existsSync(), isTrue);
+ final LocalizationsGenerator generator = setupLocalizations(<String, String>{
+ 'en': singleMessageArbFileString,
+ 'es': singleEsMessageArbFileString,
+ }, usesNullableGetter: false);
+ expect(generator.outputDirectory.existsSync(), isTrue);
+ expect(generator.outputDirectory.childFile('output-localization-file.dart').existsSync(), isTrue);
expect(
- outputDirectory.childFile('output-localization-file.dart').readAsStringSync(),
+ generator.outputDirectory.childFile('output-localization-file.dart').readAsStringSync(),
contains('static AppLocalizations of(BuildContext context)'),
);
expect(
- outputDirectory.childFile('output-localization-file.dart').readAsStringSync(),
+ generator.outputDirectory.childFile('output-localization-file.dart').readAsStringSync(),
contains('return Localizations.of<AppLocalizations>(context, AppLocalizations)!;'),
);
},
);
testWithoutContext('creates list of inputs and outputs when file path is specified', () {
- _standardFlutterDirectoryL10nSetup(fs);
-
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- inputsAndOutputsListPath: syntheticL10nPackagePath,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
-
+ setupLocalizations(<String, String>{
+ 'en': singleMessageArbFileString,
+ 'es': singleEsMessageArbFileString,
+ }, inputsAndOutputsListPath: syntheticL10nPackagePath);
final File inputsAndOutputsList = fs.file(
fs.path.join(syntheticL10nPackagePath, 'gen_l10n_inputs_and_outputs.json'),
);
@@ -731,24 +644,18 @@
});
testWithoutContext('setting both a headerString and a headerFile should fail', () {
- fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
- ..createSync(recursive: true)
- ..childFile(defaultTemplateArbFileName).writeAsStringSync(singleMessageArbFileString)
- ..childFile(esArbFileName).writeAsStringSync(singleEsMessageArbFileString)
- ..childFile('header.txt').writeAsStringSync('/// Sample header in a text file');
-
expect(
() {
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- headerString: '/// Sample header for localizations file.',
+ setupLocalizations(
+ <String, String>{
+ 'en': singleMessageArbFileString,
+ 'es': singleEsMessageArbFileString,
+ },
+ headerString: '/// Sample header in a text file',
headerFile: 'header.txt',
- logger: logger,
+ setup: (Directory l10nDirectory) {
+ l10nDirectory.childFile('header.txt').writeAsStringSync('/// Sample header in a text file');
+ },
);
},
throwsA(isA<L10nException>().having(
@@ -760,27 +667,12 @@
});
testWithoutContext('setting a headerFile that does not exist should fail', () {
- final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
- ..createSync(recursive: true);
- l10nDirectory.childFile(defaultTemplateArbFileName)
- .writeAsStringSync(singleMessageArbFileString);
- l10nDirectory.childFile(esArbFileName)
- .writeAsStringSync(singleEsMessageArbFileString);
- l10nDirectory.childFile('header.txt')
- .writeAsStringSync('/// Sample header in a text file');
-
expect(
() {
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- headerFile: 'header.tx', // Intentionally spelled incorrectly
- logger: logger,
- );
+ setupLocalizations(<String, String>{
+ 'en': singleMessageArbFileString,
+ 'es': singleEsMessageArbFileString,
+ }, headerFile: 'header.txt');
},
throwsA(isA<L10nException>().having(
(L10nException e) => e.message,
@@ -878,7 +770,7 @@
_standardFlutterDirectoryL10nSetup(fs);
// Missing flutter: generate: true should throw exception.
- fs.file(fs.path.join(syntheticPackagePath, 'pubspec.yaml'))
+ fs.file('pubspec.yaml')
..createSync(recursive: true)
..writeAsStringSync('''
flutter:
@@ -914,6 +806,34 @@
);
});
+ testWithoutContext('uses the same line terminator as pubspec.yaml', () async {
+ _standardFlutterDirectoryL10nSetup(fs);
+
+ fs.file('pubspec.yaml')
+ ..createSync(recursive: true)
+ ..writeAsStringSync('''
+flutter:\r
+ generate: true\r
+''');
+
+ final LocalizationOptions options = LocalizationOptions(
+ arbDir: fs.path.join('lib', 'l10n'),
+ outputClass: defaultClassNameString,
+ outputLocalizationFile: defaultOutputFileString,
+ );
+ await generateLocalizations(
+ fileSystem: fs,
+ options: options,
+ logger: BufferLogger.test(),
+ projectDir: fs.currentDirectory,
+ dependenciesDir: fs.currentDirectory,
+ artifacts: artifacts,
+ processManager: processManager,
+ );
+ final String content = getGeneratedFileContent(locale: 'en');
+ expect(content, contains('\r\n'));
+ });
+
testWithoutContext('blank lines generated nicely', () async {
_standardFlutterDirectoryL10nSetup(fs);
@@ -1323,28 +1243,13 @@
group('writeOutputFiles', () {
testWithoutContext('multiple messages with syntax error all log their errors', () {
- final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
- ..createSync(recursive: true);
- l10nDirectory.childFile(defaultTemplateArbFileName)
- .writeAsStringSync(r'''
+ try {
+ setupLocalizations(<String, String>{
+ 'en': r'''
{
"msg1": "{",
"msg2": "{ {"
-}''');
- l10nDirectory.childFile(esArbFileName)
- .writeAsStringSync(singleEsMessageArbFileString);
- try {
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
+}'''});
} on L10nException catch (error) {
expect(error.message, equals('Found syntax errors.'));
expect(logger.errorText, contains('''
@@ -1358,147 +1263,62 @@
});
testWithoutContext('no description generates generic comment', () {
- final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
- ..createSync(recursive: true);
- l10nDirectory.childFile(defaultTemplateArbFileName)
- .writeAsStringSync(r'''
+ setupLocalizations(<String, String>{
+ 'en': r'''
{
"helloWorld": "Hello world!"
-}''');
- l10nDirectory.childFile(esArbFileName)
- .writeAsStringSync(singleEsMessageArbFileString);
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
- final File baseLocalizationsFile = fs.file(
- fs.path.join(syntheticL10nPackagePath, 'output-localization-file.dart')
- );
- expect(baseLocalizationsFile.existsSync(), isTrue);
-
- final String baseLocalizationsFileContents = fs.file(
- fs.path.join(syntheticL10nPackagePath, 'output-localization-file.dart')
- ).readAsStringSync();
- expect(baseLocalizationsFileContents, contains('/// No description provided for @helloWorld.'));
+}'''
+ });
+ expect(getGeneratedFileContent(), contains('/// No description provided for @helloWorld.'));
});
- testWithoutContext('multiline descriptions are correctly formatted as comments', () {
- final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
- ..createSync(recursive: true);
- l10nDirectory.childFile(defaultTemplateArbFileName)
- .writeAsStringSync(r'''
+ testWithoutContext('multiline descriptions are correctly formatted as comments', () {
+ setupLocalizations(<String, String>{
+ 'en': r'''
{
"helloWorld": "Hello world!",
"@helloWorld": {
"description": "The generic example string in every language.\nUse this for tests!"
}
-}''');
- l10nDirectory.childFile(esArbFileName)
- .writeAsStringSync(singleEsMessageArbFileString);
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
- final File baseLocalizationsFile = fs.file(
- fs.path.join(syntheticL10nPackagePath, 'output-localization-file.dart')
- );
- expect(baseLocalizationsFile.existsSync(), isTrue);
-
- final String baseLocalizationsFileContents = fs.file(
- fs.path.join(syntheticL10nPackagePath, 'output-localization-file.dart')
- ).readAsStringSync();
- expect(baseLocalizationsFileContents, contains('''
+}'''});
+ expect(getGeneratedFileContent(), contains('''
/// The generic example string in every language.
/// Use this for tests!'''));
});
testWithoutContext('message without placeholders - should generate code comment with description and template message translation', () {
- _standardFlutterDirectoryL10nSetup(fs);
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
-
- final File baseLocalizationsFile = fs.file(
- fs.path.join(syntheticL10nPackagePath, 'output-localization-file.dart')
- );
- expect(baseLocalizationsFile.existsSync(), isTrue);
-
- final String baseLocalizationsFileContents = fs.file(
- fs.path.join(syntheticL10nPackagePath, 'output-localization-file.dart')
- ).readAsStringSync();
- expect(baseLocalizationsFileContents, contains('/// Title for the application.'));
- expect(baseLocalizationsFileContents, contains('''
+ setupLocalizations(<String, String> {
+ 'en': singleMessageArbFileString,
+ 'es': singleEsMessageArbFileString,
+ });
+ final String content = getGeneratedFileContent();
+ expect(content, contains('/// Title for the application.'));
+ expect(content, contains('''
/// In en, this message translates to:
/// **'Title'**'''));
});
testWithoutContext('template message translation handles newline characters', () {
- final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
- ..createSync(recursive: true);
- l10nDirectory.childFile(defaultTemplateArbFileName)
- .writeAsStringSync(r'''
+ setupLocalizations(<String, String>{
+ 'en': r'''
{
"title": "Title \n of the application",
"@title": {
"description": "Title for the application."
}
-}''');
- l10nDirectory.childFile(esArbFileName)
- .writeAsStringSync(singleEsMessageArbFileString);
-
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
-
- final File baseLocalizationsFile = fs.file(
- fs.path.join(syntheticL10nPackagePath, 'output-localization-file.dart')
- );
- expect(baseLocalizationsFile.existsSync(), isTrue);
-
- final String baseLocalizationsFileContents = fs.file(
- fs.path.join(syntheticL10nPackagePath, 'output-localization-file.dart')
- ).readAsStringSync();
- expect(baseLocalizationsFileContents, contains('/// Title for the application.'));
- expect(baseLocalizationsFileContents, contains(r'''
+}''',
+ 'es': singleEsMessageArbFileString
+ });
+ final String content = getGeneratedFileContent();
+ expect(content, contains('/// Title for the application.'));
+ expect(content, contains(r'''
/// In en, this message translates to:
/// **'Title \n of the application'**'''));
});
testWithoutContext('message with placeholders - should generate code comment with description and template message translation', () {
- final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
- ..createSync(recursive: true);
- l10nDirectory.childFile(defaultTemplateArbFileName)
- .writeAsStringSync(r'''
+ setupLocalizations(<String, String>{
+ 'en': r'''
{
"price": "The price of this item is: ${price}",
"@price": {
@@ -1510,94 +1330,41 @@
}
}
}
-}''');
- l10nDirectory.childFile(esArbFileName)
- .writeAsStringSync(r'''
+}''',
+ 'es': r'''
{
- "price": "el precio de este artículo es: ${price}"
-}''');
-
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
-
- final File baseLocalizationsFile = fs.file(
- fs.path.join(syntheticL10nPackagePath, 'output-localization-file.dart')
- );
- expect(baseLocalizationsFile.existsSync(), isTrue);
-
- final String baseLocalizationsFileContents = fs.file(
- fs.path.join(syntheticL10nPackagePath, 'output-localization-file.dart')
- ).readAsStringSync();
- expect(baseLocalizationsFileContents, contains('/// The price of an online shopping cart item.'));
- expect(baseLocalizationsFileContents, contains(r'''
+ "price": "El precio de este artículo es: ${price}"
+}'''
+ });
+ final String content = getGeneratedFileContent();
+ expect(content, contains('/// The price of an online shopping cart item.'));
+ expect(content, contains(r'''
/// In en, this message translates to:
/// **'The price of this item is: \${price}'**'''));
});
testWithoutContext('should generate a file per language', () {
- const String singleEnCaMessageArbFileString = '''
+ setupLocalizations(<String, String>{
+ 'en': singleMessageArbFileString,
+ 'en_CA': '''
{
"title": "Canadian Title"
-}''';
- fs.currentDirectory.childDirectory('lib').childDirectory('l10n')..createSync(recursive: true)
- ..childFile(defaultTemplateArbFileName).writeAsStringSync(singleMessageArbFileString)
- ..childFile('app_en_CA.arb').writeAsStringSync(singleEnCaMessageArbFileString);
-
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
-
- expect(fs.isFileSync(fs.path.join(syntheticL10nPackagePath, 'output-localization-file_en.dart')), true);
- expect(fs.isFileSync(fs.path.join(syntheticL10nPackagePath, 'output-localization-file_en_US.dart')), false);
-
- final String englishLocalizationsFile = fs.file(
- fs.path.join(syntheticL10nPackagePath, 'output-localization-file_en.dart')
- ).readAsStringSync();
- expect(englishLocalizationsFile, contains('class AppLocalizationsEnCa extends AppLocalizationsEn'));
- expect(englishLocalizationsFile, contains('class AppLocalizationsEn extends AppLocalizations'));
+}'''
+ });
+ expect(getGeneratedFileContent(locale: 'en'), contains('class AppLocalizationsEn extends AppLocalizations'));
+ expect(getGeneratedFileContent(locale: 'en'), contains('class AppLocalizationsEnCa extends AppLocalizationsEn'));
+ expect(() => getGeneratedFileContent(locale: 'en_US'), throwsException);
});
testWithoutContext('language imports are sorted when preferredSupportedLocaleString is given', () {
- fs.currentDirectory.childDirectory('lib').childDirectory('l10n')..createSync(recursive: true)
- ..childFile(defaultTemplateArbFileName).writeAsStringSync(singleMessageArbFileString)
- ..childFile('app_zh.arb').writeAsStringSync(singleZhMessageArbFileString)
- ..childFile('app_es.arb').writeAsStringSync(singleEsMessageArbFileString);
-
- const List<String> preferredSupportedLocale = <String>['zh'];
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- preferredSupportedLocales: preferredSupportedLocale,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
-
- final String localizationsFile = fs.file(
- fs.path.join(syntheticL10nPackagePath, defaultOutputFileString),
- ).readAsStringSync();
- expect(localizationsFile, contains(
+ const List<String> preferredSupportedLocales = <String>['zh'];
+ setupLocalizations(<String, String>{
+ 'en': singleMessageArbFileString,
+ 'zh': singleZhMessageArbFileString,
+ 'es': singleEsMessageArbFileString,
+ }, preferredSupportedLocales: preferredSupportedLocales);
+ final String content = getGeneratedFileContent();
+ expect(content, contains(
'''
import 'output-localization-file_en.dart';
import 'output-localization-file_es.dart';
@@ -1607,21 +1374,9 @@
// Regression test for https://github.com/flutter/flutter/issues/88356
testWithoutContext('full output file suffix is retained', () {
- fs.currentDirectory.childDirectory('lib').childDirectory('l10n')..createSync(recursive: true)
- ..childFile(defaultTemplateArbFileName).writeAsStringSync(singleMessageArbFileString);
-
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: 'output-localization-file.g.dart',
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
-
+ setupLocalizations(<String, String>{
+ 'en': singleMessageArbFileString,
+ }, outputFileString: 'output-localization-file.g.dart');
final String baseLocalizationsFile = fs.file(
fs.path.join(syntheticL10nPackagePath, 'output-localization-file.g.dart'),
).readAsStringSync();
@@ -1640,118 +1395,69 @@
});
testWithoutContext('throws an exception when invalid output file name is passed in', () {
- fs.currentDirectory.childDirectory('lib').childDirectory('l10n')..createSync(recursive: true)
- ..childFile(defaultTemplateArbFileName).writeAsStringSync(singleMessageArbFileString);
-
- expect(
- () {
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: 'asdf',
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
- },
- throwsA(isA<L10nException>().having(
- (L10nException e) => e.message,
- 'message',
- allOf(
- contains('output-localization-file'),
- contains('asdf'),
- contains('is invalid'),
- contains('The file name must have a .dart extension.'),
- ),
- )),
- );
-
- expect(
- () {
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: '.g.dart',
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
- },
- throwsA(isA<L10nException>().having(
- (L10nException e) => e.message,
- 'message',
- allOf(
- contains('output-localization-file'),
- contains('.g.dart'),
- contains('is invalid'),
- contains('The base name cannot be empty.'),
- ),
- )),
- );
- });
+ expect(
+ () {
+ setupLocalizations(<String, String>{
+ 'en': singleMessageArbFileString,
+ }, outputFileString: 'asdf');
+ },
+ throwsA(isA<L10nException>().having(
+ (L10nException e) => e.message,
+ 'message',
+ allOf(
+ contains('output-localization-file'),
+ contains('asdf'),
+ contains('is invalid'),
+ contains('The file name must have a .dart extension.'),
+ ),
+ )),
+ );
+ expect(
+ () {
+ setupLocalizations(<String, String>{
+ 'en': singleMessageArbFileString,
+ }, outputFileString: '.g.dart');
+ },
+ throwsA(isA<L10nException>().having(
+ (L10nException e) => e.message,
+ 'message',
+ allOf(
+ contains('output-localization-file'),
+ contains('.g.dart'),
+ contains('is invalid'),
+ contains('The base name cannot be empty.'),
+ ),
+ )),
+ );
+ });
testWithoutContext('imports are deferred and loaded when useDeferredImports are set', () {
- fs.currentDirectory.childDirectory('lib').childDirectory('l10n')..createSync(recursive: true)
- ..childFile(defaultTemplateArbFileName).writeAsStringSync(singleMessageArbFileString);
-
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- useDeferredLoading: true,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
-
- final String localizationsFile = fs.file(
- fs.path.join(syntheticL10nPackagePath, defaultOutputFileString),
- ).readAsStringSync();
- expect(localizationsFile, contains(
+ setupLocalizations(<String, String>{
+ 'en': singleMessageArbFileString,
+ }, useDeferredLoading: true);
+ final String content = getGeneratedFileContent();
+ expect(content, contains(
'''
import 'output-localization-file_en.dart' deferred as output-localization-file_en;
'''));
- expect(localizationsFile, contains('output-localization-file_en.loadLibrary()'));
+ expect(content, contains('output-localization-file_en.loadLibrary()'));
});
group('placeholder tests', () {
testWithoutContext('should automatically infer placeholders that are not explicitly defined', () {
- const String messageWithoutDefinedPlaceholder = '''
+ setupLocalizations(<String, String>{
+ 'en': '''
{
"helloWorld": "Hello {name}"
-}''';
-
- final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
- ..createSync(recursive: true);
- l10nDirectory.childFile(defaultTemplateArbFileName)
- .writeAsStringSync(messageWithoutDefinedPlaceholder);
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
- final String localizationsFile = fs.file(
- fs.path.join(syntheticL10nPackagePath, 'output-localization-file_en.dart'),
- ).readAsStringSync();
- expect(localizationsFile, contains('String helloWorld(Object name) {'));
+}'''
+ });
+ final String content = getGeneratedFileContent(locale: 'en');
+ expect(content, contains('String helloWorld(Object name) {'));
});
testWithoutContext('placeholder parameter list should be consistent between languages', () {
- const String messageEn = '''
+ setupLocalizations(<String, String>{
+ 'en': '''
{
"helloWorld": "Hello {name}",
"@helloWorld": {
@@ -1759,42 +1465,22 @@
"name": {}
}
}
-}''';
- const String messageEs = '''
+}''',
+ 'es': '''
{
"helloWorld": "Hola"
}
-''';
- final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
- ..createSync(recursive: true);
- l10nDirectory.childFile(defaultTemplateArbFileName)
- .writeAsStringSync(messageEn);
- l10nDirectory.childFile('app_es.arb')
- .writeAsStringSync(messageEs);
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
- final String localizationsFileEn = fs.file(
- fs.path.join(syntheticL10nPackagePath, 'output-localization-file_en.dart'),
- ).readAsStringSync();
- final String localizationsFileEs = fs.file(
- fs.path.join(syntheticL10nPackagePath, 'output-localization-file_es.dart'),
- ).readAsStringSync();
- expect(localizationsFileEn, contains('String helloWorld(Object name) {'));
- expect(localizationsFileEs, contains('String helloWorld(Object name) {'));
+''',
+ });
+ expect(getGeneratedFileContent(locale: 'en'), contains('String helloWorld(Object name) {'));
+ expect(getGeneratedFileContent(locale: 'es'), contains('String helloWorld(Object name) {'));
});
});
group('DateTime tests', () {
testWithoutContext('imports package:intl', () {
- const String singleDateMessageArbFileString = '''
+ setupLocalizations(<String, String>{
+ 'en': '''
{
"@@locale": "en",
"springBegins": "Spring begins on {springStartDate}",
@@ -1807,35 +1493,19 @@
}
}
}
-}''';
- fs.currentDirectory.childDirectory('lib').childDirectory('l10n')..createSync(recursive: true)
- ..childFile(defaultTemplateArbFileName).writeAsStringSync(singleDateMessageArbFileString);
-
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
-
- final String localizationsFile = fs.file(
- fs.path.join(syntheticL10nPackagePath, 'output-localization-file_en.dart'),
- ).readAsStringSync();
- expect(localizationsFile, contains(intlImportDartCode));
+}'''
+ });
+ expect(getGeneratedFileContent(locale: 'en'), contains(intlImportDartCode));
});
testWithoutContext('throws an exception when improperly formatted date is passed in', () {
- const String singleDateMessageArbFileString = '''
+ expect(
+ () {
+ setupLocalizations(<String, String>{
+ 'en': '''
{
- "@@locale": "en",
"springBegins": "Spring begins on {springStartDate}",
"@springBegins": {
- "description": "The first day of spring",
"placeholders": {
"springStartDate": {
"type": "DateTime",
@@ -1843,24 +1513,8 @@
}
}
}
-}''';
- final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
- ..createSync(recursive: true);
- l10nDirectory.childFile(defaultTemplateArbFileName)
- .writeAsStringSync(singleDateMessageArbFileString);
-
- expect(
- () {
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
+}'''
+ });
},
throwsA(isA<L10nException>().having(
(L10nException e) => e.message,
@@ -1875,12 +1529,11 @@
});
testWithoutContext('use standard date format whenever possible', () {
- const String singleDateMessageArbFileString = '''
+ setupLocalizations(<String, String>{
+ 'en': '''
{
- "@@locale": "en",
"springBegins": "Spring begins on {springStartDate}",
"@springBegins": {
- "description": "The first day of spring",
"placeholders": {
"springStartDate": {
"type": "DateTime",
@@ -1889,31 +1542,15 @@
}
}
}
-}''';
- final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
- ..createSync(recursive: true);
- l10nDirectory.childFile(defaultTemplateArbFileName)
- .writeAsStringSync(singleDateMessageArbFileString);
-
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
-
- final String localizationsFile = fs.file(
- fs.path.join(syntheticL10nPackagePath, 'output-localization-file_en.dart'),
- ).readAsStringSync();
- expect(localizationsFile, contains('DateFormat.yMd(localeName)'));
+}'''
+ });
+ final String content = getGeneratedFileContent(locale: 'en');
+ expect(content, contains('DateFormat.yMd(localeName)'));
});
testWithoutContext('handle arbitrary formatted date', () {
- const String singleDateMessageArbFileString = '''
+ setupLocalizations(<String, String>{
+ 'en': '''
{
"@@locale": "en",
"springBegins": "Spring begins on {springStartDate}",
@@ -1927,31 +1564,17 @@
}
}
}
-}''';
- final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
- ..createSync(recursive: true);
- l10nDirectory.childFile(defaultTemplateArbFileName)
- .writeAsStringSync(singleDateMessageArbFileString);
-
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
-
- final String localizationsFile = fs.file(
- fs.path.join(syntheticL10nPackagePath, 'output-localization-file_en.dart'),
- ).readAsStringSync();
- expect(localizationsFile, contains(r"DateFormat('asdf o\'clock', localeName)"));
+}'''
+ });
+ final String content = getGeneratedFileContent(locale: 'en');
+ expect(content, contains(r"DateFormat('asdf o\'clock', localeName)"));
});
testWithoutContext('throws an exception when no format attribute is passed in', () {
- const String singleDateMessageArbFileString = '''
+ expect(
+ () {
+ setupLocalizations(<String, String>{
+ 'en': '''
{
"springBegins": "Spring begins on {springStartDate}",
"@springBegins": {
@@ -1962,25 +1585,8 @@
}
}
}
-}''';
- final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
- ..createSync(recursive: true);
- l10nDirectory.childFile(defaultTemplateArbFileName)
- .writeAsStringSync(singleDateMessageArbFileString);
-
- expect(
- () {
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
+}'''
+ });
},
throwsA(isA<L10nException>().having(
(L10nException e) => e.message,
@@ -1993,7 +1599,8 @@
group('NumberFormat tests', () {
testWithoutContext('imports package:intl', () {
- const String singleDateMessageArbFileString = '''
+ setupLocalizations(<String, String>{
+ 'en': '''
{
"courseCompletion": "You have completed {progress} of the course.",
"@courseCompletion": {
@@ -2005,32 +1612,17 @@
}
}
}
-}''';
- fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
- ..createSync(recursive: true)
- ..childFile(defaultTemplateArbFileName).writeAsStringSync(
- singleDateMessageArbFileString);
-
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
-
- final String localizationsFile = fs.file(
- fs.path.join(syntheticL10nPackagePath, 'output-localization-file_en.dart'),
- ).readAsStringSync();
- expect(localizationsFile, contains(intlImportDartCode));
+}'''
+ });
+ final String content = getGeneratedFileContent(locale: 'en');
+ expect(content, contains(intlImportDartCode));
});
testWithoutContext('throws an exception when improperly formatted number is passed in', () {
- const String singleDateMessageArbFileString = '''
+ expect(
+ () {
+ setupLocalizations(<String, String>{
+ 'en': '''
{
"courseCompletion": "You have completed {progress} of the course.",
"@courseCompletion": {
@@ -2042,25 +1634,8 @@
}
}
}
-}''';
- final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
- ..createSync(recursive: true);
- l10nDirectory.childFile(defaultTemplateArbFileName)
- .writeAsStringSync(singleDateMessageArbFileString);
-
- expect(
- () {
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
+}'''
+ });
},
throwsA(isA<L10nException>().having(
(L10nException e) => e.message,
@@ -2076,29 +1651,24 @@
});
group('plural messages', () {
+ testWithoutContext('intl package import should be omitted in subclass files when no plurals are included', () {
+ setupLocalizations(<String, String>{
+ 'en': singleMessageArbFileString,
+ 'es': singleEsMessageArbFileString,
+ });
+ expect(getGeneratedFileContent(locale: 'es'), isNot(contains(intlImportDartCode)));
+ });
+
testWithoutContext('warnings are generated when plural parts are repeated', () {
- const String pluralMessageWithOverriddenParts = '''
+ setupLocalizations(<String, String>{
+ 'en': '''
{
"helloWorlds": "{count,plural, =0{Hello}zero{hello} other{hi}}",
"@helloWorlds": {
"description": "Properly formatted but has redundant zero cases."
}
-}''';
- final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
- ..createSync(recursive: true);
- l10nDirectory.childFile(defaultTemplateArbFileName)
- .writeAsStringSync(pluralMessageWithOverriddenParts);
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
+}'''
+ });
expect(logger.hadWarningOutput, isTrue);
expect(logger.warningText, contains('''
[app_en.arb:helloWorlds] ICU Syntax Warning: The plural part specified below is overridden by a later plural part.
@@ -2107,26 +1677,13 @@
});
testWithoutContext('undefined plural cases throws syntax error', () {
- const String pluralMessageWithUndefinedParts = '''
+ try {
+ setupLocalizations(<String, String>{
+ 'en': '''
{
"count": "{count,plural, =0{None} =1{One} =2{Two} =3{Undefined Behavior!} other{Hmm...}}"
-}''';
- final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
- ..createSync(recursive: true);
- l10nDirectory.childFile(defaultTemplateArbFileName)
- .writeAsStringSync(pluralMessageWithUndefinedParts);
- try {
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
+}'''
+ });
} on L10nException catch (error) {
expect(error.message, contains('Found syntax errors.'));
expect(logger.hadErrorOutput, isTrue);
@@ -2139,62 +1696,30 @@
});
testWithoutContext('should automatically infer plural placeholders that are not explicitly defined', () {
- const String pluralMessageWithoutPlaceholdersAttribute = '''
+ setupLocalizations(<String, String>{
+ 'en': '''
{
"helloWorlds": "{count,plural, =0{Hello}=1{Hello World}=2{Hello two worlds}few{Hello {count} worlds}many{Hello all {count} worlds}other{Hello other {count} worlds}}",
"@helloWorlds": {
"description": "Improperly formatted since it has no placeholder attribute."
}
-}''';
-
- final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
- ..createSync(recursive: true);
- l10nDirectory.childFile(defaultTemplateArbFileName)
- .writeAsStringSync(pluralMessageWithoutPlaceholdersAttribute);
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
- final String localizationsFile = fs.file(
- fs.path.join(syntheticL10nPackagePath, 'output-localization-file_en.dart'),
- ).readAsStringSync();
- expect(localizationsFile, contains('String helloWorlds(num count) {'));
+}'''
+ });
+ expect(getGeneratedFileContent(locale: 'en'), contains('String helloWorlds(num count) {'));
});
testWithoutContext('should throw attempting to generate a plural message with incorrect format for placeholders', () {
- const String pluralMessageWithIncorrectPlaceholderFormat = '''
+ expect(
+ () {
+ setupLocalizations(<String, String>{
+ 'en': '''
{
"helloWorlds": "{count,plural, =0{Hello}=1{Hello World}=2{Hello two worlds}few{Hello {count} worlds}many{Hello all {count} worlds}other{Hello other {count} worlds}}",
"@helloWorlds": {
"placeholders": "Incorrectly a string, should be a map."
}
-}''';
-
- final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
- ..createSync(recursive: true);
- l10nDirectory.childFile(defaultTemplateArbFileName)
- .writeAsStringSync(pluralMessageWithIncorrectPlaceholderFormat);
-
- expect(
- () {
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
+}'''
+ });
},
throwsA(isA<L10nException>().having(
(L10nException e) => e.message,
@@ -2210,62 +1735,30 @@
group('select messages', () {
testWithoutContext('should automatically infer select placeholders that are not explicitly defined', () {
- const String selectMessageWithoutPlaceholdersAttribute = '''
+ setupLocalizations(<String, String>{
+ 'en': '''
{
"genderSelect": "{gender, select, female {She} male {He} other {they} }",
"@genderSelect": {
"description": "Improperly formatted since it has no placeholder attribute."
}
-}''';
-
- final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
- ..createSync(recursive: true);
- l10nDirectory.childFile(defaultTemplateArbFileName)
- .writeAsStringSync(selectMessageWithoutPlaceholdersAttribute);
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
- final String localizationsFile = fs.file(
- fs.path.join(syntheticL10nPackagePath, 'output-localization-file_en.dart'),
- ).readAsStringSync();
- expect(localizationsFile, contains('String genderSelect(String gender) {'));
+}'''
+ });
+ expect(getGeneratedFileContent(locale: 'en'), contains('String genderSelect(String gender) {'));
});
testWithoutContext('should throw attempting to generate a select message with incorrect format for placeholders', () {
- const String selectMessageWithIncorrectPlaceholderFormat = '''
+ expect(
+ () {
+ setupLocalizations(<String, String>{
+ 'en': '''
{
"genderSelect": "{gender, select, female {She} male {He} other {they} }",
"@genderSelect": {
"placeholders": "Incorrectly a string, should be a map."
}
-}''';
-
- final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
- ..createSync(recursive: true);
- l10nDirectory.childFile(defaultTemplateArbFileName)
- .writeAsStringSync(selectMessageWithIncorrectPlaceholderFormat);
-
- expect(
- () {
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
+}'''
+ });
},
throwsA(isA<L10nException>().having(
(L10nException e) => e.message,
@@ -2279,7 +1772,9 @@
});
testWithoutContext('should throw attempting to generate a select message with an incorrect message', () {
- const String selectMessageWithoutPlaceholdersAttribute = '''
+ try {
+ setupLocalizations(<String, String>{
+ 'en': '''
{
"genderSelect": "{gender, select,}",
"@genderSelect": {
@@ -2287,24 +1782,8 @@
"gender": {}
}
}
-}''';
-
- final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
- ..createSync(recursive: true);
- l10nDirectory.childFile(defaultTemplateArbFileName)
- .writeAsStringSync(selectMessageWithoutPlaceholdersAttribute);
- try {
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
+}'''
+ });
} on L10nException {
expect(logger.errorText, contains('''
[app_en.arb:genderSelect] ICU Syntax Error: Select expressions must have an "other" case.
@@ -2315,36 +1794,83 @@
});
});
+ group('argument messages', () {
+ testWithoutContext('should generate proper calls to intl.DateFormat', () {
+ setupLocalizations(<String, String>{
+ 'en': '''
+{
+ "datetime": "{today, date, ::yMd}"
+}'''
+ });
+ expect(getGeneratedFileContent(locale: 'en'), contains('intl.DateFormat.yMd(localeName).format(today)'));
+ });
+
+ testWithoutContext('should generate proper calls to intl.DateFormat when using time', () {
+ setupLocalizations(<String, String>{
+ 'en': '''
+{
+ "datetime": "{current, time, ::jms}"
+}'''
+ });
+ expect(getGeneratedFileContent(locale: 'en'), contains('intl.DateFormat.jms(localeName).format(current)'));
+ });
+
+ testWithoutContext('should not complain when placeholders are explicitly typed to DateTime', () {
+ setupLocalizations(<String, String>{
+ 'en': '''
+{
+ "datetime": "{today, date, ::yMd}",
+ "@datetime": {
+ "placeholders": {
+ "today": { "type": "DateTime" }
+ }
+ }
+}'''
+ });
+ expect(getGeneratedFileContent(locale: 'en'), contains('String datetime(DateTime today) {'));
+ });
+
+ testWithoutContext('should automatically infer date time placeholders that are not explicitly defined', () {
+ setupLocalizations(<String, String>{
+ 'en': '''
+{
+ "datetime": "{today, date, ::yMd}"
+}'''
+ });
+ expect(getGeneratedFileContent(locale: 'en'), contains('String datetime(DateTime today) {'));
+ });
+
+ testWithoutContext('should throw on invalid DateFormat', () {
+ try {
+ setupLocalizations(<String, String>{
+ 'en': '''
+{
+ "datetime": "{today, date, ::yMMMMMd}"
+}'''
+ });
+ assert(false);
+ } on L10nException {
+ expect(logger.errorText, contains('Date format "yMMMMMd" for placeholder today does not have a corresponding DateFormat constructor'));
+ }
+ });
+ });
+
// All error handling for messages should collect errors on a per-error
// basis and log them out individually. Then, it will throw an L10nException.
group('error handling tests', () {
testWithoutContext('syntax/code-gen errors properly logs errors per message', () {
// TODO(thkim1011): Fix error handling so that long indents don't get truncated.
// See https://github.com/flutter/flutter/issues/120490.
- const String messagesWithSyntaxErrors = '''
+ try {
+ setupLocalizations(<String, String>{
+ 'en': '''
{
"hello": "Hello { name",
"plural": "This is an incorrectly formatted plural: { count, plural, zero{No frog} one{One frog} other{{count} frogs}",
"explanationWithLexingError": "The 'string above is incorrect as it forgets to close the brace",
"pluralWithInvalidCase": "{ count, plural, woohoo{huh?} other{lol} }"
-}''';
- try {
- final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
- ..createSync(recursive: true);
- l10nDirectory.childFile(defaultTemplateArbFileName)
- .writeAsStringSync(messagesWithSyntaxErrors);
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- useEscaping: true,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
+}'''
+ }, useEscaping: true);
} on L10nException {
expect(logger.errorText, contains('''
[app_en.arb:hello] ICU Syntax Error: Expected "}" but found no tokens.
@@ -2363,33 +1889,11 @@
});
testWithoutContext('errors thrown in multiple languages are all shown', () {
- const String messageEn = '''
-{
- "hello": "Hello { name"
-}''';
- const String messageEs = '''
-{
- "hello": "Hola { name"
-}''';
try {
- final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
- ..createSync(recursive: true);
- l10nDirectory.childFile(defaultTemplateArbFileName)
- .writeAsStringSync(messageEn);
- l10nDirectory.childFile('app_es.arb')
- .writeAsStringSync(messageEs);
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- useEscaping: true,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
+ setupLocalizations(<String, String>{
+ 'en': '{ "hello": "Hello { name" }',
+ 'es': '{ "hello": "Hola { name" }',
+ });
} on L10nException {
expect(logger.errorText, contains('''
[app_en.arb:hello] ICU Syntax Error: Expected "}" but found no tokens.
@@ -2402,28 +1906,6 @@
});
});
- testWithoutContext('intl package import should be omitted in subclass files when no plurals are included', () {
- fs.currentDirectory.childDirectory('lib').childDirectory('l10n')..createSync(recursive: true)
- ..childFile(defaultTemplateArbFileName).writeAsStringSync(singleMessageArbFileString)
- ..childFile('app_es.arb').writeAsStringSync(singleEsMessageArbFileString);
-
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
-
- final String localizationsFile = fs.file(
- fs.path.join(syntheticL10nPackagePath, 'output-localization-file_es.dart'),
- ).readAsStringSync();
- expect(localizationsFile, isNot(contains(intlImportDartCode)));
- });
testWithoutContext('intl package import should be kept in subclass files when plurals are included', () {
const String pluralMessageArb = '''
@@ -2437,33 +1919,17 @@
}
}
''';
-
const String pluralMessageEsArb = '''
{
"helloWorlds": "{count,plural, =0{ES - Hello} =1{ES - Hello World} =2{ES - Hello two worlds} few{ES - Hello {count} worlds} many{ES - Hello all {count} worlds} other{ES - Hello other {count} worlds}}"
}
''';
-
- fs.currentDirectory.childDirectory('lib').childDirectory('l10n')..createSync(recursive: true)
- ..childFile(defaultTemplateArbFileName).writeAsStringSync(pluralMessageArb)
- ..childFile('app_es.arb').writeAsStringSync(pluralMessageEsArb);
-
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
-
- final String localizationsFile = fs.file(
- fs.path.join(syntheticL10nPackagePath, 'output-localization-file_es.dart'),
- ).readAsStringSync();
- expect(localizationsFile, contains(intlImportDartCode));
+ setupLocalizations(<String, String>{
+ 'en': pluralMessageArb,
+ 'es': pluralMessageEsArb,
+ });
+ expect(getGeneratedFileContent(locale: 'en'), contains(intlImportDartCode));
+ expect(getGeneratedFileContent(locale: 'es'), contains(intlImportDartCode));
});
testWithoutContext('intl package import should be kept in subclass files when select is included', () {
@@ -2478,55 +1944,27 @@
}
}
''';
-
const String selectMessageEsArb = '''
{
"genderSelect": "{gender, select, female {ES - She} male {ES - He} other {ES - they} }"
}
''';
-
- fs.currentDirectory.childDirectory('lib').childDirectory('l10n')..createSync(recursive: true)
- ..childFile(defaultTemplateArbFileName).writeAsStringSync(selectMessageArb)
- ..childFile('app_es.arb').writeAsStringSync(selectMessageEsArb);
-
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
-
- final String localizationsFile = fs.file(
- fs.path.join(syntheticL10nPackagePath, 'output-localization-file_es.dart'),
- ).readAsStringSync();
- expect(localizationsFile, contains(intlImportDartCode));
+ setupLocalizations(<String, String>{
+ 'en': selectMessageArb,
+ 'es': selectMessageEsArb,
+ });
+ expect(getGeneratedFileContent(locale: 'en'), contains(intlImportDartCode));
+ expect(getGeneratedFileContent(locale: 'es'), contains(intlImportDartCode));
});
testWithoutContext('check indentation on generated files', () {
- _standardFlutterDirectoryL10nSetup(fs);
-
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
-
- final String localizationsFile = fs.file(
- fs.path.join(syntheticL10nPackagePath, 'output-localization-file.dart'),
- ).readAsStringSync();
+ setupLocalizations(<String, String>{
+ 'en': singleMessageArbFileString,
+ 'es': singleEsMessageArbFileString,
+ });
// Tests a few of the lines in the generated code.
// Localizations lookup code
+ final String localizationsFile = getGeneratedFileContent();
expect(localizationsFile.contains(' switch (locale.languageCode) {'), true);
expect(localizationsFile.contains(" case 'en': return AppLocalizationsEn();"), true);
expect(localizationsFile.contains(" case 'es': return AppLocalizationsEs();"), true);
@@ -2540,50 +1978,19 @@
});
testWithoutContext('foundation package import should be omitted from file template when deferred loading = true', () {
- fs.currentDirectory.childDirectory('lib').childDirectory('l10n')..createSync(recursive: true)
- ..childFile(defaultTemplateArbFileName).writeAsStringSync(singleMessageArbFileString)
- ..childFile('app_es.arb').writeAsStringSync(singleEsMessageArbFileString);
-
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- useDeferredLoading: true,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
-
- final String localizationsFile = fs.file(
- fs.path.join(syntheticL10nPackagePath, 'output-localization-file.dart'),
- ).readAsStringSync();
- expect(localizationsFile, isNot(contains(foundationImportDartCode)));
+ setupLocalizations(<String, String>{
+ 'en': singleMessageArbFileString,
+ 'es': singleEsMessageArbFileString,
+ }, useDeferredLoading: true);
+ expect(getGeneratedFileContent(), isNot(contains(foundationImportDartCode)));
});
testWithoutContext('foundation package import should be kept in file template when deferred loading = false', () {
- fs.currentDirectory.childDirectory('lib').childDirectory('l10n')..createSync(recursive: true)
- ..childFile(defaultTemplateArbFileName).writeAsStringSync(singleMessageArbFileString)
- ..childFile('app_es.arb').writeAsStringSync(singleEsMessageArbFileString);
-
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
-
- final String localizationsFile = fs.file(
- fs.path.join(syntheticL10nPackagePath, 'output-localization-file.dart'),
- ).readAsStringSync();
- expect(localizationsFile, contains(foundationImportDartCode));
+ setupLocalizations(<String, String>{
+ 'en': singleMessageArbFileString,
+ 'es': singleEsMessageArbFileString,
+ });
+ expect(getGeneratedFileContent(), contains(foundationImportDartCode));
});
testWithoutContext('check for string interpolation rules', () {
@@ -2688,27 +2095,11 @@
"nine": "m{nine}"
}
''';
-
- fs.currentDirectory.childDirectory('lib').childDirectory('l10n')..createSync(recursive: true)
- ..childFile(defaultTemplateArbFileName).writeAsStringSync(enArbCheckList)
- ..childFile('app_es.arb').writeAsStringSync(esArbCheckList);
-
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
-
- final String localizationsFile = fs.file(
- fs.path.join(syntheticL10nPackagePath, 'output-localization-file_es.dart'),
- ).readAsStringSync();
-
+ setupLocalizations(<String, String>{
+ 'en': enArbCheckList,
+ 'es': esArbCheckList,
+ });
+ final String localizationsFile = getGeneratedFileContent(locale: 'es');
expect(localizationsFile, contains(r'$one'));
expect(localizationsFile, contains(r'$two'));
expect(localizationsFile, contains(r'${three}'));
@@ -2758,27 +2149,11 @@
"second": "{count,plural, =0{test {count}} other{ {count}}}"
}
''';
-
- fs.currentDirectory.childDirectory('lib').childDirectory('l10n')..createSync(recursive: true)
- ..childFile(defaultTemplateArbFileName).writeAsStringSync(enArbCheckList)
- ..childFile('app_es.arb').writeAsStringSync(esArbCheckList);
-
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
-
- final String localizationsFile = fs.file(
- fs.path.join(syntheticL10nPackagePath, 'output-localization-file_es.dart'),
- ).readAsStringSync();
-
+ setupLocalizations(<String, String>{
+ 'en': enArbCheckList,
+ 'es': esArbCheckList,
+ });
+ final String localizationsFile = getGeneratedFileContent(locale: 'es');
expect(localizationsFile, contains(r'test $count test'));
expect(localizationsFile, contains(r'哈$count哈'));
expect(localizationsFile, contains(r'm${count}m'));
@@ -2803,24 +2178,9 @@
"description": "Title for the Stocks application"
},
}''';
- final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
- ..createSync(recursive: true);
- l10nDirectory.childFile(defaultTemplateArbFileName)
- .writeAsStringSync(arbFileWithTrailingComma);
-
expect(
() {
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
+ setupLocalizations(<String, String>{ 'en': arbFileWithTrailingComma });
},
throwsA(isA<L10nException>().having(
(L10nException e) => e.message,
@@ -2840,25 +2200,12 @@
{
"title": "Stocks"
}''';
- final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
- ..createSync(recursive: true);
- l10nDirectory.childFile(defaultTemplateArbFileName)
- .writeAsStringSync(arbFileWithMissingResourceAttribute);
-
expect(
() {
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- areResourceAttributesRequired: true,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
+ setupLocalizations(
+ <String, String>{ 'en': arbFileWithMissingResourceAttribute },
+ areResourceAttributeRequired: true,
+ );
},
throwsA(isA<L10nException>().having(
(L10nException e) => e.message,
@@ -2877,25 +2224,8 @@
"description": "Title for the Stocks application"
}
}''';
- final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
- ..createSync(recursive: true);
- l10nDirectory.childFile(defaultTemplateArbFileName)
- .writeAsStringSync(nonAlphaNumericArbFile);
-
expect(
- () {
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
- },
+ () => setupLocalizations(<String, String>{ 'en': nonAlphaNumericArbFile }),
throwsA(isA<L10nException>().having(
(L10nException e) => e.message,
'message',
@@ -2912,25 +2242,8 @@
"description": "Title for the Stocks application"
}
}''';
- final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
- ..createSync(recursive: true);
- l10nDirectory.childFile(defaultTemplateArbFileName)
- .writeAsStringSync(nonAlphaNumericArbFile);
-
expect(
- () {
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
- },
+ () => setupLocalizations(<String, String>{ 'en': nonAlphaNumericArbFile }),
throwsA(isA<L10nException>().having(
(L10nException e) => e.message,
'message',
@@ -2947,24 +2260,8 @@
"description": "Title for the Stocks application"
}
}''';
- final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
- ..createSync(recursive: true);
- l10nDirectory.childFile(defaultTemplateArbFileName)
- .writeAsStringSync(nonAlphaNumericArbFile);
-
expect(
- () {
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
- },
+ () => setupLocalizations(<String, String>{ 'en': nonAlphaNumericArbFile }),
throwsA(isA<L10nException>().having(
(L10nException e) => e.message,
'message',
@@ -2981,21 +2278,7 @@
"description": "Title for the application"
}
}''';
- final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
- ..createSync(recursive: true);
- l10nDirectory.childFile(defaultTemplateArbFileName)
- .writeAsStringSync(dollarArbFile);
-
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
+ setupLocalizations(<String, String>{ 'en': dollarArbFile });
});
});
@@ -3035,18 +2318,9 @@
});
testWithoutContext('should generate a valid pubspec.yaml file when using synthetic package if it does not already exist', () {
- _standardFlutterDirectoryL10nSetup(fs);
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
-
+ setupLocalizations(<String, String>{
+ 'en': singleMessageArbFileString,
+ });
final Directory outputDirectory = fs.directory(syntheticPackagePath);
final File pubspecFile = outputDirectory.childFile('pubspec.yaml');
expect(pubspecFile.existsSync(), isTrue);
@@ -3062,22 +2336,12 @@
});
testWithoutContext('should not overwrite existing pubspec.yaml file when using synthetic package', () {
- _standardFlutterDirectoryL10nSetup(fs);
final File pubspecFile = fs.file(fs.path.join(syntheticPackagePath, 'pubspec.yaml'))
..createSync(recursive: true)
..writeAsStringSync('abcd');
-
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
-
+ setupLocalizations(<String, String>{
+ 'en': singleMessageArbFileString,
+ });
// The original pubspec file should not be overwritten.
expect(pubspecFile.readAsStringSync(), 'abcd');
});
@@ -3095,57 +2359,20 @@
}
}
}''';
-
- final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
- ..createSync(recursive: true);
- l10nDirectory.childFile(defaultTemplateArbFileName)
- .writeAsStringSync(arbFile);
-
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
-
- final String localizationsFile = fs.file(
- fs.path.join(syntheticL10nPackagePath, 'output-localization-file_en.dart'),
- ).readAsStringSync();
- expect(localizationsFile, containsIgnoringWhitespace(r'''
+ setupLocalizations(<String, String>{
+ 'en': arbFile,
+ });
+ expect(getGeneratedFileContent(locale: 'en'), containsIgnoringWhitespace(r'''
String orderNumber(int number) {
return 'This is order #$number.';
}
'''));
- expect(localizationsFile, isNot(contains(intlImportDartCode)));
+ expect(getGeneratedFileContent(locale: 'en'), isNot(contains(intlImportDartCode)));
});
testWithoutContext('app localizations lookup is a public method', () {
- final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
- ..createSync(recursive: true);
- l10nDirectory.childFile(defaultTemplateArbFileName)
- .writeAsStringSync(singleMessageArbFileString);
-
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
-
- final String localizationsFile = fs.file(
- fs.path.join(syntheticL10nPackagePath, 'output-localization-file.dart'),
- ).readAsStringSync();
- expect(localizationsFile, containsIgnoringWhitespace(r'''
+ setupLocalizations(<String, String>{ 'en': singleMessageArbFileString });
+ expect(getGeneratedFileContent(), containsIgnoringWhitespace(r'''
AppLocalizations lookupAppLocalizations(Locale locale) {
'''));
});
@@ -3158,29 +2385,8 @@
"description": "A message with a single quote."
}
}''';
-
- final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
- ..createSync(recursive: true);
- l10nDirectory.childFile(defaultTemplateArbFileName)
- .writeAsStringSync(arbFile);
-
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- useEscaping: true,
- )
- ..loadResources()
- ..writeOutputFiles();
-
- final String localizationsFile = fs.file(
- fs.path.join(syntheticL10nPackagePath, 'output-localization-file_en.dart'),
- ).readAsStringSync();
- expect(localizationsFile, contains(r"Flutter\'s amazing"));
+ setupLocalizations(<String, String>{ 'en': arbFile }, useEscaping: true);
+ expect(getGeneratedFileContent(locale: 'en'), contains(r"Flutter\'s amazing"));
});
testWithoutContext('suppress warnings flag actually suppresses warnings', () {
@@ -3194,22 +2400,10 @@
}
}
}''';
- final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
- ..createSync(recursive: true);
- l10nDirectory.childFile(defaultTemplateArbFileName)
- .writeAsStringSync(pluralMessageWithOverriddenParts);
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
+ setupLocalizations(
+ <String, String>{ 'en': pluralMessageWithOverriddenParts },
suppressWarnings: true,
- )
- ..loadResources()
- ..writeOutputFiles();
+ );
expect(logger.hadWarningOutput, isFalse);
});
@@ -3229,27 +2423,8 @@
}
}
}''';
-
- final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
- ..createSync(recursive: true);
- l10nDirectory.childFile(defaultTemplateArbFileName)
- .writeAsStringSync(arbFile);
-
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- )
- ..loadResources()
- ..writeOutputFiles();
-
- final String localizationsFile = fs.file(
- fs.path.join(syntheticL10nPackagePath, 'output-localization-file_en.dart'),
- ).readAsStringSync();
+ setupLocalizations(<String, String>{ 'en': arbFile });
+ final String localizationsFile = getGeneratedFileContent(locale: 'en');
expect(localizationsFile, containsIgnoringWhitespace(r'''
String treeHeight(double height) {
'''));
@@ -3267,25 +2442,7 @@
{
"dollarSignWithSelect": "$nice_bug\nHello Bug! Manifistation #1 {selectPlaceholder, select, case{message} other{messageOther}}"
}''';
- final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
- ..createSync(recursive: true);
- l10nDirectory.childFile(defaultTemplateArbFileName)
- .writeAsStringSync(dollarSignWithSelect);
- LocalizationsGenerator(
- fileSystem: fs,
- inputPathString: defaultL10nPathString,
- outputPathString: defaultL10nPathString,
- templateArbFileName: defaultTemplateArbFileName,
- outputFileString: defaultOutputFileString,
- classNameString: defaultClassNameString,
- logger: logger,
- suppressWarnings: true,
- )
- ..loadResources()
- ..writeOutputFiles();
- final String localizationsFile = fs.file(
- fs.path.join(syntheticL10nPackagePath, 'output-localization-file_en.dart'),
- ).readAsStringSync();
- expect(localizationsFile, contains(r'\$nice_bug\nHello Bug! Manifistation #1 $_temp0'));
+ setupLocalizations(<String, String>{ 'en': dollarSignWithSelect });
+ expect(getGeneratedFileContent(locale: 'en'), contains(r'\$nice_bug\nHello Bug! Manifistation #1 $_temp0'));
});
}
diff --git a/packages/flutter_tools/test/general.shard/intellij/intellij_validator_test.dart b/packages/flutter_tools/test/general.shard/intellij/intellij_validator_test.dart
index eab4b0b..bd7f810 100644
--- a/packages/flutter_tools/test/general.shard/intellij/intellij_validator_test.dart
+++ b/packages/flutter_tools/test/general.shard/intellij/intellij_validator_test.dart
@@ -305,6 +305,7 @@
processManager: processManager,
plistParser: FakePlistParser(<String, String>{
PlistParser.kCFBundleShortVersionStringKey: '2020.10',
+ PlistParser.kCFBundleIdentifierKey: 'com.jetbrains.intellij',
}),
).whereType<IntelliJValidatorOnMac>();
expect(validators.length, 2);
@@ -371,6 +372,47 @@
expect(validator.pluginsPath, '/path/to/JetBrainsToolboxApp.plugins');
});
+
+ testWithoutContext('Remove JetBrains Toolbox', () async {
+ final FileSystem fileSystem = MemoryFileSystem.test();
+ final List<String> installPaths = <String>[
+ fileSystem.path.join('/', 'foo', 'bar', 'Applications',
+ 'JetBrains Toolbox', 'IntelliJ IDEA Ultimate.app'),
+ fileSystem.path.join('/', 'foo', 'bar', 'Applications',
+ 'JetBrains Toolbox', 'IntelliJ IDEA Community Edition.app')
+ ];
+
+ for (final String installPath in installPaths) {
+ fileSystem.directory(installPath).createSync(recursive: true);
+ }
+
+ final FakeProcessManager processManager =
+ FakeProcessManager.list(<FakeCommand>[
+ const FakeCommand(command: <String>[
+ 'mdfind',
+ 'kMDItemCFBundleIdentifier="com.jetbrains.intellij.ce"',
+ ], stdout: 'skip'),
+ const FakeCommand(command: <String>[
+ 'mdfind',
+ 'kMDItemCFBundleIdentifier="com.jetbrains.intellij*"',
+ ], stdout: 'skip')
+ ]);
+
+ final Iterable<DoctorValidator> installed =
+ IntelliJValidatorOnMac.installed(
+ fileSystem: fileSystem,
+ fileSystemUtils:
+ FileSystemUtils(fileSystem: fileSystem, platform: macPlatform),
+ userMessages: UserMessages(),
+ plistParser: FakePlistParser(<String, String>{
+ 'JetBrainsToolboxApp': '/path/to/JetBrainsToolboxApp',
+ 'CFBundleIdentifier': 'com.jetbrains.toolbox.linkapp',
+ }),
+ processManager: processManager,
+ );
+
+ expect(installed.length, 0);
+ });
}
class IntelliJValidatorTestTarget extends IntelliJValidator {
diff --git a/packages/flutter_tools/test/general.shard/ios/devices_test.dart b/packages/flutter_tools/test/general.shard/ios/devices_test.dart
index 73105f7..cb222d9 100644
--- a/packages/flutter_tools/test/general.shard/ios/devices_test.dart
+++ b/packages/flutter_tools/test/general.shard/ios/devices_test.dart
@@ -13,6 +13,7 @@
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/os.dart';
import 'package:flutter_tools/src/base/platform.dart';
+import 'package:flutter_tools/src/base/version.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/device.dart';
@@ -177,6 +178,121 @@
).majorSdkVersion, 0);
});
+ testWithoutContext('parses sdk version', () {
+ Version? sdkVersion = IOSDevice(
+ 'device-123',
+ iProxy: IProxy.test(logger: logger, processManager: FakeProcessManager.any()),
+ fileSystem: fileSystem,
+ logger: logger,
+ platform: macPlatform,
+ iosDeploy: iosDeploy,
+ iMobileDevice: iMobileDevice,
+ name: 'iPhone 1',
+ cpuArchitecture: DarwinArch.arm64,
+ sdkVersion: '13.3.1',
+ connectionInterface: DeviceConnectionInterface.attached,
+ isConnected: true,
+ devModeEnabled: true,
+ ).sdkVersion;
+ Version expectedVersion = Version(13, 3, 1, text: '13.3.1');
+ expect(sdkVersion, isNotNull);
+ expect(sdkVersion!.toString(), expectedVersion.toString());
+ expect(sdkVersion.compareTo(expectedVersion), 0);
+
+ sdkVersion = IOSDevice(
+ 'device-123',
+ iProxy: IProxy.test(logger: logger, processManager: FakeProcessManager.any()),
+ fileSystem: fileSystem,
+ logger: logger,
+ platform: macPlatform,
+ iosDeploy: iosDeploy,
+ iMobileDevice: iMobileDevice,
+ name: 'iPhone 1',
+ cpuArchitecture: DarwinArch.arm64,
+ sdkVersion: '13.3.1 (20ADBC)',
+ connectionInterface: DeviceConnectionInterface.attached,
+ isConnected: true,
+ devModeEnabled: true,
+ ).sdkVersion;
+ expectedVersion = Version(13, 3, 1, text: '13.3.1 (20ADBC)');
+ expect(sdkVersion, isNotNull);
+ expect(sdkVersion!.toString(), expectedVersion.toString());
+ expect(sdkVersion.compareTo(expectedVersion), 0);
+
+ sdkVersion = IOSDevice(
+ 'device-123',
+ iProxy: IProxy.test(logger: logger, processManager: FakeProcessManager.any()),
+ fileSystem: fileSystem,
+ logger: logger,
+ platform: macPlatform,
+ iosDeploy: iosDeploy,
+ iMobileDevice: iMobileDevice,
+ name: 'iPhone 1',
+ cpuArchitecture: DarwinArch.arm64,
+ sdkVersion: '16.4.1(a) (20ADBC)',
+ connectionInterface: DeviceConnectionInterface.attached,
+ isConnected: true,
+ devModeEnabled: true,
+ ).sdkVersion;
+ expectedVersion = Version(16, 4, 1, text: '16.4.1(a) (20ADBC)');
+ expect(sdkVersion, isNotNull);
+ expect(sdkVersion!.toString(), expectedVersion.toString());
+ expect(sdkVersion.compareTo(expectedVersion), 0);
+
+ sdkVersion = IOSDevice(
+ 'device-123',
+ iProxy: IProxy.test(logger: logger, processManager: FakeProcessManager.any()),
+ fileSystem: fileSystem,
+ logger: logger,
+ platform: macPlatform,
+ iosDeploy: iosDeploy,
+ iMobileDevice: iMobileDevice,
+ name: 'iPhone 1',
+ cpuArchitecture: DarwinArch.arm64,
+ sdkVersion: '0',
+ connectionInterface: DeviceConnectionInterface.attached,
+ isConnected: true,
+ devModeEnabled: true,
+ ).sdkVersion;
+ expectedVersion = Version(0, 0, 0, text: '0');
+ expect(sdkVersion, isNotNull);
+ expect(sdkVersion!.toString(), expectedVersion.toString());
+ expect(sdkVersion.compareTo(expectedVersion), 0);
+
+ sdkVersion = IOSDevice(
+ 'device-123',
+ iProxy: IProxy.test(logger: logger, processManager: FakeProcessManager.any()),
+ fileSystem: fileSystem,
+ logger: logger,
+ platform: macPlatform,
+ iosDeploy: iosDeploy,
+ iMobileDevice: iMobileDevice,
+ name: 'iPhone 1',
+ cpuArchitecture: DarwinArch.arm64,
+ connectionInterface: DeviceConnectionInterface.attached,
+ isConnected: true,
+ devModeEnabled: true,
+ ).sdkVersion;
+ expect(sdkVersion, isNull);
+
+ sdkVersion = IOSDevice(
+ 'device-123',
+ iProxy: IProxy.test(logger: logger, processManager: FakeProcessManager.any()),
+ fileSystem: fileSystem,
+ logger: logger,
+ platform: macPlatform,
+ iosDeploy: iosDeploy,
+ iMobileDevice: iMobileDevice,
+ name: 'iPhone 1',
+ cpuArchitecture: DarwinArch.arm64,
+ sdkVersion: 'bogus',
+ connectionInterface: DeviceConnectionInterface.attached,
+ isConnected: true,
+ devModeEnabled: true,
+ ).sdkVersion;
+ expect(sdkVersion, isNull);
+ });
+
testWithoutContext('has build number in sdkNameAndVersion', () async {
final IOSDevice device = IOSDevice(
'device-123',
diff --git a/packages/flutter_tools/test/general.shard/ios/ios_deploy_test.dart b/packages/flutter_tools/test/general.shard/ios/ios_deploy_test.dart
index 72e4538..e5bce99 100644
--- a/packages/flutter_tools/test/general.shard/ios/ios_deploy_test.dart
+++ b/packages/flutter_tools/test/general.shard/ios/ios_deploy_test.dart
@@ -341,6 +341,33 @@
await iosDeployDebugger.launchAndAttach();
expect(logger.errorText, contains('Try launching from within Xcode'));
});
+
+ testWithoutContext('debugger attached and received logs', () async {
+ final StreamController<List<int>> stdin = StreamController<List<int>>();
+ final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
+ FakeCommand(
+ command: const <String>['ios-deploy'],
+ stdout: '(lldb) run\r\nsuccess\r\nLog on attach1\r\n\r\nLog on attach2\r\n',
+ stdin: IOSink(stdin.sink),
+ ),
+ ]);
+ final IOSDeployDebugger iosDeployDebugger = IOSDeployDebugger.test(
+ processManager: processManager,
+ logger: logger,
+ );
+ final List<String> receivedLogLines = <String>[];
+ final Stream<String> logLines = iosDeployDebugger.logLines
+ ..listen(receivedLogLines.add);
+
+ expect(iosDeployDebugger.logLines, emitsInOrder(<String>[
+ 'Log on attach1',
+ 'Log on attach2',
+ ]));
+ expect(await iosDeployDebugger.launchAndAttach(), isTrue);
+ await logLines.drain();
+
+ expect(LineSplitter.split(logger.traceText), containsOnce('Received logs from ios-deploy.'));
+ });
});
testWithoutContext('detach', () async {
diff --git a/packages/flutter_tools/test/general.shard/ios/simulators_test.dart b/packages/flutter_tools/test/general.shard/ios/simulators_test.dart
index cefad20..e285783 100644
--- a/packages/flutter_tools/test/general.shard/ios/simulators_test.dart
+++ b/packages/flutter_tools/test/general.shard/ios/simulators_test.dart
@@ -1204,7 +1204,7 @@
@override
Future<RunResult> launch(String deviceId, String appIdentifier, [ List<String>? launchArgs ]) async {
- requests.add(LaunchRequest(deviceId, appIdentifier, launchArgs));
+ requests.add(LaunchRequest(appIdentifier, launchArgs));
return RunResult(ProcessResult(0, 0, '', ''), <String>['test']);
}
@@ -1215,9 +1215,8 @@
}
class LaunchRequest {
- const LaunchRequest(this.deviceId, this.appIdentifier, this.launchArgs);
+ const LaunchRequest(this.appIdentifier, this.launchArgs);
- final String deviceId;
final String appIdentifier;
final List<String>? launchArgs;
}
diff --git a/packages/flutter_tools/test/general.shard/macos/application_package_test.dart b/packages/flutter_tools/test/general.shard/macos/application_package_test.dart
index 40652af..1edfa13 100644
--- a/packages/flutter_tools/test/general.shard/macos/application_package_test.dart
+++ b/packages/flutter_tools/test/general.shard/macos/application_package_test.dart
@@ -167,7 +167,7 @@
const BuildInfo flavoredApp = BuildInfo(BuildMode.release, 'flavor', treeShakeIcons: false);
applicationBundle = macosApp.bundleDirectory(flavoredApp);
- expect(applicationBundle, 'Release Flavor');
+ expect(applicationBundle, 'Release-flavor');
}, overrides: overrides);
});
diff --git a/packages/flutter_tools/test/general.shard/macos/xcode_test.dart b/packages/flutter_tools/test/general.shard/macos/xcode_test.dart
index b7fd7ff..f2b2142 100644
--- a/packages/flutter_tools/test/general.shard/macos/xcode_test.dart
+++ b/packages/flutter_tools/test/general.shard/macos/xcode_test.dart
@@ -791,7 +791,7 @@
"available" : true,
"platform" : "com.apple.platform.iphoneos",
"modelCode" : "iPhone8,1",
- "identifier" : "d83d5bc53967baa0ee18626ba87b6254b2ab5418",
+ "identifier" : "43ad2fda7991b34fe1acbda82f9e2fd3d6ddc9f7",
"architecture" : "BOGUS",
"modelName" : "Future iPad",
"name" : "iPad"
@@ -865,6 +865,190 @@
Platform: () => macPlatform,
});
+ testUsingContext('use connected entry when filtering out duplicates', () async {
+ const String devicesOutput = '''
+[
+ {
+ "simulator" : false,
+ "operatingSystemVersion" : "13.3 (17C54)",
+ "interface" : "usb",
+ "available" : false,
+ "platform" : "com.apple.platform.iphoneos",
+ "modelCode" : "iPhone8,1",
+ "identifier" : "c4ca6f7a53027d1b7e4972e28478e7a28e2faee2",
+ "architecture" : "arm64",
+ "modelName" : "iPhone 6s",
+ "name" : "iPhone"
+ },
+ {
+ "simulator" : false,
+ "operatingSystemVersion" : "13.3 (17C54)",
+ "interface" : "usb",
+ "available" : false,
+ "platform" : "com.apple.platform.iphoneos",
+ "modelCode" : "iPhone8,1",
+ "identifier" : "c4ca6f7a53027d1b7e4972e28478e7a28e2faee2",
+ "architecture" : "arm64",
+ "modelName" : "iPhone 6s",
+ "name" : "iPhone",
+ "error" : {
+ "code" : -13,
+ "failureReason" : "",
+ "description" : "iPhone iPad is not connected",
+ "recoverySuggestion" : "Xcode will continue when iPhone is connected and unlocked.",
+ "domain" : "com.apple.platform.iphoneos"
+ }
+ }
+]
+''';
+
+ fakeProcessManager.addCommand(const FakeCommand(
+ command: <String>['xcrun', 'xcdevice', 'list', '--timeout', '2'],
+ stdout: devicesOutput,
+ ));
+ final List<IOSDevice> devices = await xcdevice.getAvailableIOSDevices();
+ expect(devices, hasLength(1));
+
+ expect(devices[0].id, 'c4ca6f7a53027d1b7e4972e28478e7a28e2faee2');
+ expect(devices[0].name, 'iPhone');
+ expect(await devices[0].sdkNameAndVersion, 'iOS 13.3 17C54');
+ expect(devices[0].cpuArchitecture, DarwinArch.arm64);
+ expect(devices[0].connectionInterface, DeviceConnectionInterface.attached);
+ expect(devices[0].isConnected, true);
+
+ expect(fakeProcessManager, hasNoRemainingExpectations);
+ }, overrides: <Type, Generator>{
+ Platform: () => macPlatform,
+ Artifacts: () => Artifacts.test(),
+ });
+
+ testUsingContext('use entry with sdk when filtering out duplicates', () async {
+ const String devicesOutput = '''
+[
+ {
+ "simulator" : false,
+ "interface" : "usb",
+ "available" : false,
+ "platform" : "com.apple.platform.iphoneos",
+ "modelCode" : "iPhone8,1",
+ "identifier" : "c4ca6f7a53027d1b7e4972e28478e7a28e2faee2",
+ "architecture" : "arm64",
+ "modelName" : "iPhone 6s",
+ "name" : "iPhone_1",
+ "error" : {
+ "code" : -13,
+ "failureReason" : "",
+ "description" : "iPhone iPad is not connected",
+ "recoverySuggestion" : "Xcode will continue when iPhone is connected and unlocked.",
+ "domain" : "com.apple.platform.iphoneos"
+ }
+ },
+ {
+ "simulator" : false,
+ "operatingSystemVersion" : "13.3 (17C54)",
+ "interface" : "usb",
+ "available" : false,
+ "platform" : "com.apple.platform.iphoneos",
+ "modelCode" : "iPhone8,1",
+ "identifier" : "c4ca6f7a53027d1b7e4972e28478e7a28e2faee2",
+ "architecture" : "arm64",
+ "modelName" : "iPhone 6s",
+ "name" : "iPhone_2",
+ "error" : {
+ "code" : -13,
+ "failureReason" : "",
+ "description" : "iPhone iPad is not connected",
+ "recoverySuggestion" : "Xcode will continue when iPhone is connected and unlocked.",
+ "domain" : "com.apple.platform.iphoneos"
+ }
+ }
+]
+''';
+
+ fakeProcessManager.addCommand(const FakeCommand(
+ command: <String>['xcrun', 'xcdevice', 'list', '--timeout', '2'],
+ stdout: devicesOutput,
+ ));
+ final List<IOSDevice> devices = await xcdevice.getAvailableIOSDevices();
+ expect(devices, hasLength(1));
+
+ expect(devices[0].id, 'c4ca6f7a53027d1b7e4972e28478e7a28e2faee2');
+ expect(devices[0].name, 'iPhone_2');
+ expect(await devices[0].sdkNameAndVersion, 'iOS 13.3 17C54');
+ expect(devices[0].cpuArchitecture, DarwinArch.arm64);
+ expect(devices[0].connectionInterface, DeviceConnectionInterface.attached);
+ expect(devices[0].isConnected, false);
+
+ expect(fakeProcessManager, hasNoRemainingExpectations);
+ }, overrides: <Type, Generator>{
+ Platform: () => macPlatform,
+ Artifacts: () => Artifacts.test(),
+ });
+
+ testUsingContext('use entry with higher sdk when filtering out duplicates', () async {
+ const String devicesOutput = '''
+[
+ {
+ "simulator" : false,
+ "operatingSystemVersion" : "14.3 (17C54)",
+ "interface" : "usb",
+ "available" : false,
+ "platform" : "com.apple.platform.iphoneos",
+ "modelCode" : "iPhone8,1",
+ "identifier" : "c4ca6f7a53027d1b7e4972e28478e7a28e2faee2",
+ "architecture" : "arm64",
+ "modelName" : "iPhone 6s",
+ "name" : "iPhone_1",
+ "error" : {
+ "code" : -13,
+ "failureReason" : "",
+ "description" : "iPhone iPad is not connected",
+ "recoverySuggestion" : "Xcode will continue when iPhone is connected and unlocked.",
+ "domain" : "com.apple.platform.iphoneos"
+ }
+ },
+ {
+ "simulator" : false,
+ "operatingSystemVersion" : "13.3 (17C54)",
+ "interface" : "usb",
+ "available" : false,
+ "platform" : "com.apple.platform.iphoneos",
+ "modelCode" : "iPhone8,1",
+ "identifier" : "c4ca6f7a53027d1b7e4972e28478e7a28e2faee2",
+ "architecture" : "arm64",
+ "modelName" : "iPhone 6s",
+ "name" : "iPhone_2",
+ "error" : {
+ "code" : -13,
+ "failureReason" : "",
+ "description" : "iPhone iPad is not connected",
+ "recoverySuggestion" : "Xcode will continue when iPhone is connected and unlocked.",
+ "domain" : "com.apple.platform.iphoneos"
+ }
+ }
+]
+''';
+
+ fakeProcessManager.addCommand(const FakeCommand(
+ command: <String>['xcrun', 'xcdevice', 'list', '--timeout', '2'],
+ stdout: devicesOutput,
+ ));
+ final List<IOSDevice> devices = await xcdevice.getAvailableIOSDevices();
+ expect(devices, hasLength(1));
+
+ expect(devices[0].id, 'c4ca6f7a53027d1b7e4972e28478e7a28e2faee2');
+ expect(devices[0].name, 'iPhone_1');
+ expect(await devices[0].sdkNameAndVersion, 'iOS 14.3 17C54');
+ expect(devices[0].cpuArchitecture, DarwinArch.arm64);
+ expect(devices[0].connectionInterface, DeviceConnectionInterface.attached);
+ expect(devices[0].isConnected, false);
+
+ expect(fakeProcessManager, hasNoRemainingExpectations);
+ }, overrides: <Type, Generator>{
+ Platform: () => macPlatform,
+ Artifacts: () => Artifacts.test(),
+ });
+
testUsingContext('handles bad output',() async {
fakeProcessManager.addCommand(const FakeCommand(
command: <String>['xcrun', 'xcdevice', 'list', '--timeout', '2'],
diff --git a/packages/flutter_tools/test/general.shard/message_parser_test.dart b/packages/flutter_tools/test/general.shard/message_parser_test.dart
index 4d19d18..efc9680 100644
--- a/packages/flutter_tools/test/general.shard/message_parser_test.dart
+++ b/packages/flutter_tools/test/general.shard/message_parser_test.dart
@@ -306,6 +306,25 @@
])
));
+ expect(Parser('argumentTest', 'app_en.arb', 'Today is {date, date, ::yMMd}').parse(), equals(
+ Node(ST.message, 0, children: <Node>[
+ Node(ST.string, 0, value: 'Today is '),
+ Node(ST.argumentExpr, 9, children: <Node>[
+ Node(ST.openBrace, 9, value: '{'),
+ Node(ST.identifier, 10, value: 'date'),
+ Node(ST.comma, 14, value: ','),
+ Node(ST.argType, 16, children: <Node>[
+ Node(ST.date, 16, value: 'date'),
+ ]),
+ Node(ST.comma, 20, value: ','),
+ Node(ST.colon, 22, value: ':'),
+ Node(ST.colon, 23, value: ':'),
+ Node(ST.identifier, 24, value: 'yMMd'),
+ Node(ST.closeBrace, 28, value: '}'),
+ ]),
+ ])
+ ));
+
expect(Parser(
'plural',
'app_en.arb',
diff --git a/packages/flutter_tools/test/general.shard/resident_devtools_handler_test.dart b/packages/flutter_tools/test/general.shard/resident_devtools_handler_test.dart
index 8c36d4e..56d9332 100644
--- a/packages/flutter_tools/test/general.shard/resident_devtools_handler_test.dart
+++ b/packages/flutter_tools/test/general.shard/resident_devtools_handler_test.dart
@@ -156,6 +156,7 @@
},
),
listViews,
+ listViews,
const FakeVmServiceRequest(
method: 'ext.flutter.activeDevToolsServerAddress',
args: <String, Object>{
@@ -163,7 +164,6 @@
'value': 'http://localhost:8080',
},
),
- listViews,
const FakeVmServiceRequest(
method: 'ext.flutter.connectedVmServiceUri',
args: <String, Object>{
@@ -314,6 +314,7 @@
},
),
listViews,
+ listViews,
const FakeVmServiceRequest(
method: 'ext.flutter.activeDevToolsServerAddress',
args: <String, Object>{
@@ -321,7 +322,6 @@
'value': 'http://localhost:8080',
},
),
- listViews,
const FakeVmServiceRequest(
method: 'ext.flutter.connectedVmServiceUri',
args: <String, Object>{
diff --git a/packages/flutter_tools/test/general.shard/resident_runner_test.dart b/packages/flutter_tools/test/general.shard/resident_runner_test.dart
index e37e2f6..35970ba 100644
--- a/packages/flutter_tools/test/general.shard/resident_runner_test.dart
+++ b/packages/flutter_tools/test/general.shard/resident_runner_test.dart
@@ -45,12 +45,19 @@
import '../src/fakes.dart';
import '../src/testbed.dart';
+final vm_service.Event fakeUnpausedEvent = vm_service.Event(
+ kind: vm_service.EventKind.kResume,
+ timestamp: 0
+);
+
+final vm_service.Event fakePausedEvent = vm_service.Event(
+ kind: vm_service.EventKind.kPauseException,
+ timestamp: 0
+);
+
final vm_service.Isolate fakeUnpausedIsolate = vm_service.Isolate(
id: '1',
- pauseEvent: vm_service.Event(
- kind: vm_service.EventKind.kResume,
- timestamp: 0
- ),
+ pauseEvent: fakeUnpausedEvent,
breakpoints: <vm_service.Breakpoint>[],
extensionRPCs: <String>[],
libraries: <vm_service.LibraryRef>[
@@ -72,10 +79,7 @@
final vm_service.Isolate fakePausedIsolate = vm_service.Isolate(
id: '1',
- pauseEvent: vm_service.Event(
- kind: vm_service.EventKind.kPauseException,
- timestamp: 0
- ),
+ pauseEvent: fakePausedEvent,
breakpoints: <vm_service.Breakpoint>[
vm_service.Breakpoint(
breakpointNumber: 123,
@@ -537,11 +541,11 @@
listViews,
listViews,
FakeVmServiceRequest(
- method: 'getIsolate',
+ method: 'getIsolatePauseEvent',
args: <String, Object>{
'isolateId': '1',
},
- jsonResponse: fakeUnpausedIsolate.toJson(),
+ jsonResponse: fakeUnpausedEvent.toJson(),
),
FakeVmServiceRequest(
method: 'ext.flutter.reassemble',
@@ -604,11 +608,11 @@
},
),
FakeVmServiceRequest(
- method: 'getIsolate',
+ method: 'getIsolatePauseEvent',
args: <String, Object>{
'isolateId': '1',
},
- jsonResponse: fakeUnpausedIsolate.toJson(),
+ jsonResponse: fakeUnpausedEvent.toJson(),
),
FakeVmServiceRequest(
method: 'ext.flutter.reassemble',
@@ -728,11 +732,11 @@
},
),
FakeVmServiceRequest(
- method: 'getIsolate',
+ method: 'getIsolatePauseEvent',
args: <String, Object>{
'isolateId': '1',
},
- jsonResponse: fakeUnpausedIsolate.toJson(),
+ jsonResponse: fakeUnpausedEvent.toJson(),
),
FakeVmServiceRequest(
method: 'ext.flutter.reassemble',
@@ -791,11 +795,11 @@
},
),
FakeVmServiceRequest(
- method: 'getIsolate',
+ method: 'getIsolatePauseEvent',
args: <String, Object>{
'isolateId': '1',
},
- jsonResponse: fakeUnpausedIsolate.toJson(),
+ jsonResponse: fakeUnpausedEvent.toJson(),
),
FakeVmServiceRequest(
method: 'ext.flutter.fastReassemble',
@@ -882,11 +886,11 @@
},
),
FakeVmServiceRequest(
- method: 'getIsolate',
+ method: 'getIsolatePauseEvent',
args: <String, Object>{
'isolateId': '1',
},
- jsonResponse: fakeUnpausedIsolate.toJson(),
+ jsonResponse: fakeUnpausedEvent.toJson(),
),
FakeVmServiceRequest(
method: 'ext.flutter.fastReassemble',
diff --git a/packages/flutter_tools/test/general.shard/runner/target_devices_test.dart b/packages/flutter_tools/test/general.shard/runner/target_devices_test.dart
index d19b0c7..6c89db8 100644
--- a/packages/flutter_tools/test/general.shard/runner/target_devices_test.dart
+++ b/packages/flutter_tools/test/general.shard/runner/target_devices_test.dart
@@ -1459,7 +1459,7 @@
logger: logger,
);
targetDevices.waitForWirelessBeforeInput = true;
- targetDevices.deviceSelection.input = '1';
+ targetDevices.deviceSelection.input = <String>['1'];
logger.originalStatusText = '''
Connected devices:
target-device-9 (mobile) • xxx • ios • iOS 16
@@ -1486,6 +1486,49 @@
}, overrides: <Type, Generator>{
AnsiTerminal: () => terminal,
});
+
+
+ testUsingContext('handle invalid options for device', () async {
+ deviceManager.iosDiscoverer.deviceList = <Device>[nonEphemeralDevice];
+
+ final TestTargetDevicesWithExtendedWirelessDeviceDiscovery targetDevices = TestTargetDevicesWithExtendedWirelessDeviceDiscovery(
+ deviceManager: deviceManager,
+ logger: logger,
+ );
+ targetDevices.waitForWirelessBeforeInput = true;
+
+ // Having the '0' first is an invalid choice for a device, the second
+ // item in the list is a '2' which is out of range since we only have
+ // one item in the deviceList. The final item in the list, is '1'
+ // which is a valid option though which will return a valid device
+ //
+ // Important: if none of the values in the list are valid, the test will
+ // hang indefinitely since the [userSelectDevice()] method uses a while
+ // loop to listen for valid devices
+ targetDevices.deviceSelection.input = <String>['0', '2', '1'];
+ logger.originalStatusText = '''
+Connected devices:
+target-device-9 (mobile) • xxx • ios • iOS 16
+
+Checking for wireless devices...
+
+[1]: target-device-9 (xxx)
+''';
+
+ final List<Device>? devices = await targetDevices.findAllTargetDevices();
+
+ expect(logger.statusText, equals('''
+Connected devices:
+target-device-9 (mobile) • xxx • ios • iOS 16
+
+No wireless devices were found.
+
+[1]: target-device-9 (xxx)
+Please choose one (or "q" to quit): '''));
+ expect(devices, <Device>[nonEphemeralDevice]);
+ }, overrides: <Type, Generator>{
+ AnsiTerminal: () => terminal,
+ });
});
group('without stdinHasTerminal', () {
@@ -1753,7 +1796,7 @@
];
targetDevices.waitForWirelessBeforeInput = true;
- targetDevices.deviceSelection.input = '3';
+ targetDevices.deviceSelection.input = <String>['3'];
logger.originalStatusText = '''
Connected devices:
target-device-1 (mobile) • xxx • ios • iOS 16
@@ -1791,7 +1834,7 @@
deviceManager.iosDiscoverer.deviceList = <Device>[attachedIOSDevice1, attachedIOSDevice2];
targetDevices.waitForWirelessBeforeInput = true;
- targetDevices.deviceSelection.input = '2';
+ targetDevices.deviceSelection.input = <String>['2'];
logger.originalStatusText = '''
Connected devices:
target-device-1 (mobile) • xxx • ios • iOS 16
@@ -1828,7 +1871,7 @@
deviceManager.iosDiscoverer.refreshDeviceList = <Device>[connectedWirelessIOSDevice1, connectedWirelessIOSDevice2];
targetDevices.waitForWirelessBeforeInput = true;
- targetDevices.deviceSelection.input = '2';
+ targetDevices.deviceSelection.input = <String>['2'];
terminal.setPrompt(<String>['1', '2', 'q', 'Q'], '1');
final List<Device>? devices = await targetDevices.findAllTargetDevices();
@@ -1906,7 +1949,7 @@
deviceManager.iosDiscoverer.deviceList = <Device>[attachedIOSDevice1, attachedIOSDevice2];
targetDevices.waitForWirelessBeforeInput = true;
- targetDevices.deviceSelection.input = '2';
+ targetDevices.deviceSelection.input = <String>['2'];
logger.originalStatusText = '''
Connected devices:
target-device-1 (mobile) • xxx • ios • iOS 16
@@ -1951,7 +1994,7 @@
deviceManager.iosDiscoverer.refreshDeviceList = <Device>[attachedIOSDevice1, attachedIOSDevice2, connectedWirelessIOSDevice1];
targetDevices.waitForWirelessBeforeInput = true;
- targetDevices.deviceSelection.input = '2';
+ targetDevices.deviceSelection.input = <String>['2'];
logger.originalStatusText = '''
Connected devices:
target-device-1 (mobile) • xxx • ios • iOS 16
@@ -2133,7 +2176,7 @@
];
targetDevices.waitForWirelessBeforeInput = true;
- targetDevices.deviceSelection.input = '3';
+ targetDevices.deviceSelection.input = <String>['3'];
logger.originalStatusText = '''
Found multiple devices with name or id matching target-device:
target-device-1 (mobile) • xxx • ios • iOS 16
@@ -2173,7 +2216,7 @@
deviceManager.iosDiscoverer.deviceList = <Device>[attachedIOSDevice1, attachedIOSDevice2];
targetDevices.waitForWirelessBeforeInput = true;
- targetDevices.deviceSelection.input = '2';
+ targetDevices.deviceSelection.input = <String>['2'];
logger.originalStatusText = '''
Found multiple devices with name or id matching target-device:
target-device-1 (mobile) • xxx • ios • iOS 16
@@ -2443,11 +2486,21 @@
class TestTargetDeviceSelection extends TargetDeviceSelection {
TestTargetDeviceSelection(super.logger);
- String input = '';
+ List<String> input = <String>[];
@override
Future<String> readUserInput() async {
- return input;
+ // If only one value is provided for the input, continue
+ // to return that one input value without popping
+ //
+ // If more than one input values are provided, we are simulating
+ // the user selecting more than one option for a device, so we will pop
+ // them out from the front
+ if (input.length > 1) {
+ return input.removeAt(0);
+ }
+
+ return input[0];
}
}
diff --git a/packages/flutter_tools/test/general.shard/terminal_handler_test.dart b/packages/flutter_tools/test/general.shard/terminal_handler_test.dart
index 5992956..e234825 100644
--- a/packages/flutter_tools/test/general.shard/terminal_handler_test.dart
+++ b/packages/flutter_tools/test/general.shard/terminal_handler_test.dart
@@ -1496,7 +1496,6 @@
class TestRunner extends Fake implements ResidentRunner {
bool hasHelpBeenPrinted = false;
- String? receivedCommand;
@override
Future<void> cleanupAfterSignal() async { }
diff --git a/packages/flutter_tools/test/general.shard/update_packages_test.dart b/packages/flutter_tools/test/general.shard/update_packages_test.dart
index 7323186..b92fe6b 100644
--- a/packages/flutter_tools/test/general.shard/update_packages_test.dart
+++ b/packages/flutter_tools/test/general.shard/update_packages_test.dart
@@ -108,7 +108,6 @@
'material_color_utilities',
'url_launcher_android',
'archive',
- 'path_provider_android',
]),
);
});
diff --git a/packages/flutter_tools/test/general.shard/version_test.dart b/packages/flutter_tools/test/general.shard/version_test.dart
index 6fe0044..ab4c730 100644
--- a/packages/flutter_tools/test/general.shard/version_test.dart
+++ b/packages/flutter_tools/test/general.shard/version_test.dart
@@ -4,12 +4,13 @@
import 'dart:convert';
+import 'package:file/file.dart';
+import 'package:file/memory.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/base/process.dart';
import 'package:flutter_tools/src/base/time.dart';
import 'package:flutter_tools/src/cache.dart';
-import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:flutter_tools/src/version.dart';
import 'package:test/fake.dart';
@@ -18,7 +19,7 @@
import '../src/fake_process_manager.dart';
import '../src/fakes.dart' show FakeFlutterVersion;
-final SystemClock _testClock = SystemClock.fixed(DateTime(2015));
+final SystemClock _testClock = SystemClock.fixed(DateTime.utc(2015));
final DateTime _stampUpToDate = _testClock.ago(VersionFreshnessValidator.checkAgeConsideredUpToDate ~/ 2);
final DateTime _stampOutOfDate = _testClock.ago(VersionFreshnessValidator.checkAgeConsideredUpToDate * 2);
@@ -49,7 +50,11 @@
}
group('$FlutterVersion for $channel', () {
+ late FileSystem fs;
+ const String flutterRoot = '/path/to/flutter';
+
setUpAll(() {
+ fs = MemoryFileSystem.test();
Cache.disableLocking();
VersionFreshnessValidator.timeToPauseToLetUserReadTheMessage = Duration.zero;
});
@@ -101,7 +106,7 @@
),
]);
- final FlutterVersion flutterVersion = globals.flutterVersion;
+ final FlutterVersion flutterVersion = FlutterVersion(clock: _testClock, fs: fs, flutterRoot: flutterRoot);
await flutterVersion.checkFlutterVersionFreshness();
expect(flutterVersion.channel, channel);
expect(flutterVersion.repositoryUrl, flutterUpstreamUrl);
@@ -124,7 +129,6 @@
expect(testLogger.statusText, isEmpty);
expect(processManager, hasNoRemainingExpectations);
}, overrides: <Type, Generator>{
- FlutterVersion: () => FlutterVersion(clock: _testClock),
ProcessManager: () => processManager,
Cache: () => cache,
});
@@ -419,15 +423,197 @@
),
]);
- final FlutterVersion flutterVersion = globals.flutterVersion;
+ final MemoryFileSystem fs = MemoryFileSystem.test();
+ final FlutterVersion flutterVersion = FlutterVersion(
+ clock: _testClock,
+ fs: fs,
+ flutterRoot: '/path/to/flutter',
+ );
expect(flutterVersion.channel, '[user-branch]');
expect(flutterVersion.getVersionString(), 'feature-branch/1234abcd');
expect(flutterVersion.getBranchName(), 'feature-branch');
expect(flutterVersion.getVersionString(redactUnknownBranches: true), '[user-branch]/1234abcd');
expect(flutterVersion.getBranchName(redactUnknownBranches: true), '[user-branch]');
+
expect(processManager, hasNoRemainingExpectations);
}, overrides: <Type, Generator>{
- FlutterVersion: () => FlutterVersion(clock: _testClock),
+ ProcessManager: () => processManager,
+ Cache: () => cache,
+ });
+
+ testUsingContext('ensureVersionFile() writes version information to disk', () async {
+ processManager.addCommands(<FakeCommand>[
+ const FakeCommand(
+ command: <String>['git', '-c', 'log.showSignature=false', 'log', '-n', '1', '--pretty=format:%H'],
+ stdout: '1234abcd',
+ ),
+ const FakeCommand(
+ command: <String>['git', 'tag', '--points-at', '1234abcd'],
+ ),
+ const FakeCommand(
+ command: <String>['git', 'describe', '--match', '*.*.*', '--long', '--tags', '1234abcd'],
+ stdout: '0.1.2-3-1234abcd',
+ ),
+ const FakeCommand(
+ command: <String>['git', 'symbolic-ref', '--short', 'HEAD'],
+ stdout: 'feature-branch',
+ ),
+ const FakeCommand(
+ command: <String>['git', 'rev-parse', '--abbrev-ref', '--symbolic', '@{upstream}'],
+ ),
+ FakeCommand(
+ command: const <String>[
+ 'git',
+ '-c',
+ 'log.showSignature=false',
+ 'log',
+ 'HEAD',
+ '-n',
+ '1',
+ '--pretty=format:%ad',
+ '--date=iso',
+ ],
+ stdout: _testClock.ago(VersionFreshnessValidator.versionAgeConsideredUpToDate('stable') ~/ 2).toString(),
+ ),
+ ]);
+
+ final MemoryFileSystem fs = MemoryFileSystem.test();
+ final Directory flutterRoot = fs.directory('/path/to/flutter');
+ flutterRoot.childDirectory('bin').childDirectory('cache').createSync(recursive: true);
+ final FlutterVersion flutterVersion = FlutterVersion(
+ clock: _testClock,
+ fs: fs,
+ flutterRoot: flutterRoot.path,
+ );
+
+ final File versionFile = fs.file('/path/to/flutter/bin/cache/flutter.version.json');
+ expect(versionFile.existsSync(), isFalse);
+
+ flutterVersion.ensureVersionFile();
+ expect(versionFile.existsSync(), isTrue);
+ expect(versionFile.readAsStringSync(), '''
+{
+ "frameworkVersion": "0.0.0-unknown",
+ "channel": "[user-branch]",
+ "repositoryUrl": "unknown source",
+ "frameworkRevision": "1234abcd",
+ "frameworkCommitDate": "2014-10-02 00:00:00.000Z",
+ "engineRevision": "abcdefg",
+ "dartSdkVersion": "2.12.0",
+ "devToolsVersion": "2.8.0",
+ "flutterVersion": "0.0.0-unknown"
+}''');
+ expect(processManager, hasNoRemainingExpectations);
+ }, overrides: <Type, Generator>{
+ ProcessManager: () => processManager,
+ Cache: () => cache,
+ });
+
+ testUsingContext('version does not call git if a .version.json file exists', () async {
+ final MemoryFileSystem fs = MemoryFileSystem.test();
+ final Directory flutterRoot = fs.directory('/path/to/flutter');
+ final Directory cacheDir = flutterRoot
+ .childDirectory('bin')
+ .childDirectory('cache')
+ ..createSync(recursive: true);
+ const String devToolsVersion = '0000000';
+ const Map<String, Object> versionJson = <String, Object>{
+ 'channel': 'stable',
+ 'frameworkVersion': '1.2.3',
+ 'repositoryUrl': 'https://github.com/flutter/flutter.git',
+ 'frameworkRevision': '1234abcd',
+ 'frameworkCommitDate': '2023-04-28 12:34:56 -0400',
+ 'engineRevision': 'deadbeef',
+ 'dartSdkVersion': 'deadbeef2',
+ 'devToolsVersion': devToolsVersion,
+ 'flutterVersion': 'foo',
+ };
+ cacheDir.childFile('flutter.version.json').writeAsStringSync(
+ jsonEncode(versionJson),
+ );
+ final FlutterVersion flutterVersion = FlutterVersion(
+ clock: _testClock,
+ fs: fs,
+ flutterRoot: flutterRoot.path,
+ );
+ expect(flutterVersion.channel, 'stable');
+ expect(flutterVersion.getVersionString(), 'stable/1.2.3');
+ expect(flutterVersion.getBranchName(), 'stable');
+ expect(flutterVersion.dartSdkVersion, 'deadbeef2');
+ expect(flutterVersion.devToolsVersion, devToolsVersion);
+ expect(flutterVersion.engineRevision, 'deadbeef');
+
+ expect(processManager, hasNoRemainingExpectations);
+ }, overrides: <Type, Generator>{
+ ProcessManager: () => processManager,
+ Cache: () => cache,
+ });
+
+ testUsingContext('FlutterVersion() falls back to git if .version.json is malformed', () async {
+ final MemoryFileSystem fs = MemoryFileSystem.test();
+ final Directory flutterRoot = fs.directory(fs.path.join('path', 'to', 'flutter'));
+ final Directory cacheDir = flutterRoot
+ .childDirectory('bin')
+ .childDirectory('cache')
+ ..createSync(recursive: true);
+ final File legacyVersionFile = flutterRoot.childFile('version');
+ final File versionFile = cacheDir.childFile('flutter.version.json')..writeAsStringSync(
+ '{',
+ );
+
+ processManager.addCommands(<FakeCommand>[
+ const FakeCommand(
+ command: <String>['git', '-c', 'log.showSignature=false', 'log', '-n', '1', '--pretty=format:%H'],
+ stdout: '1234abcd',
+ ),
+ const FakeCommand(
+ command: <String>['git', 'tag', '--points-at', '1234abcd'],
+ ),
+ const FakeCommand(
+ command: <String>['git', 'describe', '--match', '*.*.*', '--long', '--tags', '1234abcd'],
+ stdout: '0.1.2-3-1234abcd',
+ ),
+ const FakeCommand(
+ command: <String>['git', 'symbolic-ref', '--short', 'HEAD'],
+ stdout: 'feature-branch',
+ ),
+ const FakeCommand(
+ command: <String>['git', 'rev-parse', '--abbrev-ref', '--symbolic', '@{upstream}'],
+ stdout: 'feature-branch',
+ ),
+ FakeCommand(
+ command: const <String>[
+ 'git',
+ '-c',
+ 'log.showSignature=false',
+ 'log',
+ 'HEAD',
+ '-n',
+ '1',
+ '--pretty=format:%ad',
+ '--date=iso',
+ ],
+ stdout: _testClock.ago(VersionFreshnessValidator.versionAgeConsideredUpToDate('stable') ~/ 2).toString(),
+ ),
+ ]);
+
+ // version file exists in a malformed state
+ expect(versionFile.existsSync(), isTrue);
+ final FlutterVersion flutterVersion = FlutterVersion(
+ clock: _testClock,
+ fs: fs,
+ flutterRoot: flutterRoot.path,
+ );
+
+ // version file was deleted because it couldn't be parsed
+ expect(versionFile.existsSync(), isFalse);
+ expect(legacyVersionFile.existsSync(), isFalse);
+ // version file was written to disk
+ flutterVersion.ensureVersionFile();
+ expect(processManager, hasNoRemainingExpectations);
+ expect(versionFile.existsSync(), isTrue);
+ expect(legacyVersionFile.existsSync(), isTrue);
+ }, overrides: <Type, Generator>{
ProcessManager: () => processManager,
Cache: () => cache,
});
diff --git a/packages/flutter_tools/test/general.shard/web/bootstrap_test.dart b/packages/flutter_tools/test/general.shard/web/bootstrap_test.dart
index f0c28e1..b2f3ad7 100644
--- a/packages/flutter_tools/test/general.shard/web/bootstrap_test.dart
+++ b/packages/flutter_tools/test/general.shard/web/bootstrap_test.dart
@@ -62,6 +62,18 @@
expect(result, matches(regex), reason: 'require.config must have a waitSeconds: 0 config entry');
});
+ test('generateMainModule hides requireJS injected by DDC', () {
+ final String result = generateMainModule(
+ entrypoint: 'foo/bar/main.js',
+ nullAssertions: false,
+ nativeNullAssertions: false,
+ );
+ expect(result, contains('''define._amd = define.amd;'''),
+ reason: 'define.amd must be preserved as _amd so users may restore it if needed.');
+ expect(result, contains('''delete define.amd;'''),
+ reason: "define.amd must be removed so packages don't attempt to use Dart's instance.");
+ });
+
test('generateMainModule embeds urls correctly', () {
final String result = generateMainModule(
entrypoint: 'foo/bar/main.js',
diff --git a/packages/flutter_tools/test/general.shard/web/devfs_web_test.dart b/packages/flutter_tools/test/general.shard/web/devfs_web_test.dart
index f65db99..e457408 100644
--- a/packages/flutter_tools/test/general.shard/web/devfs_web_test.dart
+++ b/packages/flutter_tools/test/general.shard/web/devfs_web_test.dart
@@ -1211,11 +1211,9 @@
}
class FakeDwds extends Fake implements Dwds {
- FakeDwds(this.connectedAppsIterable) :
+ FakeDwds(Iterable<AppConnection> connectedAppsIterable) :
connectedApps = Stream<AppConnection>.fromIterable(connectedAppsIterable);
- final Iterable<AppConnection> connectedAppsIterable;
-
@override
final Stream<AppConnection> connectedApps;
diff --git a/packages/flutter_tools/test/general.shard/web/devices_test.dart b/packages/flutter_tools/test/general.shard/web/devices_test.dart
index c5c9b9d..06f4d0c 100644
--- a/packages/flutter_tools/test/general.shard/web/devices_test.dart
+++ b/packages/flutter_tools/test/general.shard/web/devices_test.dart
@@ -394,12 +394,6 @@
class TestChromiumLauncher implements ChromiumLauncher {
TestChromiumLauncher();
- bool _hasInstance = false;
- void setInstance(Chromium chromium) {
- _hasInstance = true;
- currentCompleter.complete(chromium);
- }
-
@override
Completer<Chromium> currentCompleter = Completer<Chromium>();
@@ -417,7 +411,7 @@
}
@override
- bool get hasChromeInstance => _hasInstance;
+ bool get hasChromeInstance => false;
@override
Future<Chromium> launch(
diff --git a/packages/flutter_tools/test/general.shard/xcode_backend_test.dart b/packages/flutter_tools/test/general.shard/xcode_backend_test.dart
index fe7bb29..482e4ed 100644
--- a/packages/flutter_tools/test/general.shard/xcode_backend_test.dart
+++ b/packages/flutter_tools/test/general.shard/xcode_backend_test.dart
@@ -235,11 +235,6 @@
String stderr = '';
@override
- bool existsDir(String path) {
- return fileSystem.directory(path).existsSync();
- }
-
- @override
bool existsFile(String path) {
return fileSystem.file(path).existsSync();
}
diff --git a/packages/flutter_tools/test/integration.shard/analyze_once_test.dart b/packages/flutter_tools/test/integration.shard/analyze_once_test.dart
index 7424bd4..6c993dd 100644
--- a/packages/flutter_tools/test/integration.shard/analyze_once_test.dart
+++ b/packages/flutter_tools/test/integration.shard/analyze_once_test.dart
@@ -27,10 +27,7 @@
'--no-color',
...arguments,
], workingDirectory: projectPath);
- printOnFailure('Output of flutter ${arguments.join(" ")}');
- printOnFailure(result.stdout.toString());
- printOnFailure(result.stderr.toString());
- expect(result.exitCode, exitCode, reason: 'Expected to exit with non-zero exit code.');
+ expect(result, ProcessResultMatcher(exitCode: exitCode));
assertContains(result.stdout.toString(), statusTextContains);
assertContains(result.stdout.toString(), errorTextContains);
expect(result.stderr, contains(exitMessageContains));
diff --git a/packages/flutter_tools/test/integration.shard/analyze_suggestions_integration_test.dart b/packages/flutter_tools/test/integration.shard/analyze_suggestions_integration_test.dart
index c4c37ab..bac0d2f 100644
--- a/packages/flutter_tools/test/integration.shard/analyze_suggestions_integration_test.dart
+++ b/packages/flutter_tools/test/integration.shard/analyze_suggestions_integration_test.dart
@@ -158,7 +158,6 @@
expect(decoded['FlutterProject.isModule'], false);
expect(decoded['FlutterProject.isPlugin'], false);
expect(decoded['FlutterProject.manifest.appname'], 'test_project');
- expect(decoded['FlutterVersion.frameworkRevision'], '');
expect(decoded['Platform.isAndroid'], false);
expect(decoded['Platform.isIOS'], false);
diff --git a/packages/flutter_tools/test/integration.shard/android_e2e_api_test.dart b/packages/flutter_tools/test/integration.shard/android_e2e_api_test.dart
index a409a96..73d11c6 100644
--- a/packages/flutter_tools/test/integration.shard/android_e2e_api_test.dart
+++ b/packages/flutter_tools/test/integration.shard/android_e2e_api_test.dart
@@ -27,7 +27,7 @@
tempDir.path,
'--project-name=testapp',
], workingDirectory: tempDir.path);
- expect(result.exitCode, 0);
+ expect(result, const ProcessResultMatcher());
final File api33File = tempDir
.childDirectory('android')
@@ -68,7 +68,6 @@
'build',
'apk',
], workingDirectory: tempDir.path);
- expect(result.exitCode, 0);
- expect(result.stdout.toString(), contains('app-release.apk'));
+ expect(result, const ProcessResultMatcher(stdoutPattern: 'app-release.apk'));
});
}
diff --git a/packages/flutter_tools/test/integration.shard/android_gradle_java_version_test.dart b/packages/flutter_tools/test/integration.shard/android_gradle_java_version_test.dart
index cfc9cef..6dea448 100644
--- a/packages/flutter_tools/test/integration.shard/android_gradle_java_version_test.dart
+++ b/packages/flutter_tools/test/integration.shard/android_gradle_java_version_test.dart
@@ -32,7 +32,7 @@
tempDir.path,
'--project-name=testapp',
], workingDirectory: tempDir.path);
- expect(result.exitCode, 0);
+ expect(result, const ProcessResultMatcher());
// Ensure that gradle files exists from templates.
result = await processManager.run(<String>[
flutterBin,
@@ -40,7 +40,7 @@
'apk',
'--config-only',
], workingDirectory: tempDir.path);
- expect(result.exitCode, 0);
+ expect(result, const ProcessResultMatcher());
final Directory androidApp = tempDir.childDirectory('android');
result = await processManager.run(<String>[
@@ -50,7 +50,7 @@
'javaVersion',
], workingDirectory: androidApp.path);
// Verify that gradlew has a javaVersion task.
- expect(result.exitCode, 0);
+ expect(result, const ProcessResultMatcher());
// Verify the format is a number on its own line.
expect(result.stdout.toString(), matches(RegExp(r'\d+$', multiLine: true)));
});
diff --git a/packages/flutter_tools/test/integration.shard/build_ios_config_only_test.dart b/packages/flutter_tools/test/integration.shard/build_ios_config_only_test.dart
index 21d7141..86adcfb 100644
--- a/packages/flutter_tools/test/integration.shard/build_ios_config_only_test.dart
+++ b/packages/flutter_tools/test/integration.shard/build_ios_config_only_test.dart
@@ -37,13 +37,7 @@
];
final ProcessResult firstRunResult = await processManager.run(buildCommand, workingDirectory: workingDirectory);
- printOnFailure('Output of flutter build ios:');
- final String firstRunStdout = firstRunResult.stdout.toString();
- printOnFailure('First run stdout: $firstRunStdout');
- printOnFailure('First run stderr: ${firstRunResult.stderr}');
-
- expect(firstRunResult.exitCode, 0);
- expect(firstRunStdout, contains('Running pod install'));
+ expect(firstRunResult, const ProcessResultMatcher(stdoutPattern: 'Running pod install'));
final File generatedConfig = fileSystem.file(fileSystem.path.join(
workingDirectory,
@@ -71,10 +65,8 @@
// Run again with no changes.
final ProcessResult secondRunResult = await processManager.run(buildCommand, workingDirectory: workingDirectory);
final String secondRunStdout = secondRunResult.stdout.toString();
- printOnFailure('Second run stdout: $secondRunStdout');
- printOnFailure('Second run stderr: ${secondRunResult.stderr}');
- expect(secondRunResult.exitCode, 0);
+ expect(secondRunResult, const ProcessResultMatcher());
// Do not run "pod install" when nothing changes.
expect(secondRunStdout, isNot(contains('pod install')));
}, skip: !platform.isMacOS); // [intended] iOS builds only work on macos.
diff --git a/packages/flutter_tools/test/integration.shard/debug_adapter/flutter_adapter_test.dart b/packages/flutter_tools/test/integration.shard/debug_adapter/flutter_adapter_test.dart
index 01ccf59..a717a6d 100644
--- a/packages/flutter_tools/test/integration.shard/debug_adapter/flutter_adapter_test.dart
+++ b/packages/flutter_tools/test/integration.shard/debug_adapter/flutter_adapter_test.dart
@@ -256,6 +256,24 @@
allowExtras: true,
);
+ // Repeat the test for hot reload with custom syntax.
+ final Future<List<String>> customOutputEventsFuture = dap.client.stdoutOutput
+ // But skip any topLevelFunctions that come before the reload.
+ .skipWhile((String output) => output.startsWith('topLevelFunction'))
+ .take(2)
+ .toList();
+
+ await dap.client.customSyntaxHotReload();
+
+ expectLines(
+ (await customOutputEventsFuture).join(),
+ <Object>[
+ startsWith('Reloaded'),
+ 'topLevelFunction',
+ ],
+ allowExtras: true,
+ );
+
await dap.client.terminate();
});
diff --git a/packages/flutter_tools/test/integration.shard/debug_adapter/test_client.dart b/packages/flutter_tools/test/integration.shard/debug_adapter/test_client.dart
index 875913d..8857d4d 100644
--- a/packages/flutter_tools/test/integration.shard/debug_adapter/test_client.dart
+++ b/packages/flutter_tools/test/integration.shard/debug_adapter/test_client.dart
@@ -111,6 +111,11 @@
return custom('hotReload');
}
+ /// Sends a custom request with custom syntax convention to the debug adapter to trigger a Hot Reload.
+ Future<Response> customSyntaxHotReload() {
+ return custom(r'$/hotReload');
+ }
+
/// Sends a custom request to the debug adapter to trigger a Hot Restart.
Future<Response> hotRestart() {
return custom('hotRestart');
diff --git a/packages/flutter_tools/test/integration.shard/devtools_uri_test.dart b/packages/flutter_tools/test/integration.shard/devtools_uri_test.dart
new file mode 100644
index 0000000..af15861
--- /dev/null
+++ b/packages/flutter_tools/test/integration.shard/devtools_uri_test.dart
@@ -0,0 +1,53 @@
+// Copyright 2014 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'dart:async';
+
+import 'package:flutter_tools/src/base/file_system.dart';
+import 'package:flutter_tools/src/base/io.dart';
+import 'package:flutter_tools/src/convert.dart';
+
+import '../src/common.dart';
+import 'test_data/basic_project.dart';
+import 'test_utils.dart';
+
+void main() {
+ late Directory tempDir;
+ final BasicProject project = BasicProject();
+
+ setUp(() async {
+ tempDir = createResolvedTempDirectorySync('run_test.');
+ await project.setUpIn(tempDir);
+ });
+
+ tearDown(() async {
+ tryToDelete(tempDir);
+ });
+
+ // Regression test for https://github.com/flutter/flutter/issues/126691
+ testWithoutContext('flutter run --start-paused prints DevTools URI', () async {
+ final Completer<void> completer = Completer<void>();
+ const String matcher = 'The Flutter DevTools debugger and profiler on';
+
+ final String flutterBin = fileSystem.path.join(getFlutterRoot(), 'bin', 'flutter');
+ final Process process = await processManager.start(<String>[
+ flutterBin,
+ 'run',
+ '--start-paused',
+ '-d',
+ 'flutter-tester',
+ ], workingDirectory: tempDir.path);
+
+ final StreamSubscription<String> sub;
+ sub = process.stdout.transform(utf8.decoder).listen((String message) {
+ if (message.contains(matcher)) {
+ completer.complete();
+ }
+ });
+ await completer.future;
+ await sub.cancel();
+ process.kill();
+ await process.exitCode;
+ });
+}
diff --git a/packages/flutter_tools/test/integration.shard/downgrade_upgrade_integration_test.dart b/packages/flutter_tools/test/integration.shard/downgrade_upgrade_integration_test.dart
index 26ac875..8ca82c0 100644
--- a/packages/flutter_tools/test/integration.shard/downgrade_upgrade_integration_test.dart
+++ b/packages/flutter_tools/test/integration.shard/downgrade_upgrade_integration_test.dart
@@ -43,8 +43,6 @@
final Directory testDirectory = parentDirectory.childDirectory('flutter');
testDirectory.createSync(recursive: true);
- int exitCode = 0;
-
// Enable longpaths for windows integration test.
await processManager.run(<String>[
'git', 'config', '--system', 'core.longpaths', 'true',
diff --git a/packages/flutter_tools/test/integration.shard/exit_code_test.dart b/packages/flutter_tools/test/integration.shard/exit_code_test.dart
index 88d07b3..e919a6e 100644
--- a/packages/flutter_tools/test/integration.shard/exit_code_test.dart
+++ b/packages/flutter_tools/test/integration.shard/exit_code_test.dart
@@ -34,10 +34,7 @@
fileSystem.path.join(tempDir.path, 'main.dart'),
]);
- printOnFailure('Output of dart main.dart:');
- printOnFailure(result.stdout.toString());
- printOnFailure(result.stderr.toString());
- expect(result.exitCode, 0);
+ expect(result, const ProcessResultMatcher());
});
testWithoutContext('dart.sh/bat can return a non-zero exit code', () async {
@@ -54,9 +51,6 @@
fileSystem.path.join(tempDir.path, 'main.dart'),
]);
- printOnFailure('Output of dart main.dart:');
- printOnFailure(result.stdout.toString());
- printOnFailure(result.stderr.toString());
- expect(result.exitCode, 1);
+ expect(result, const ProcessResultMatcher(exitCode: 1));
});
}
diff --git a/packages/flutter_tools/test/integration.shard/flutter_build_config_only_test.dart b/packages/flutter_tools/test/integration.shard/flutter_build_config_only_test.dart
index 55d7930..92f3814 100644
--- a/packages/flutter_tools/test/integration.shard/flutter_build_config_only_test.dart
+++ b/packages/flutter_tools/test/integration.shard/flutter_build_config_only_test.dart
@@ -24,14 +24,18 @@
);
exampleAppDir = tempDir.childDirectory('bbb').childDirectory('example');
- processManager.runSync(<String>[
- flutterBin,
- ...getLocalEngineArguments(),
- 'create',
- '--template=plugin',
- '--platforms=android',
- 'bbb',
- ], workingDirectory: tempDir.path);
+ processManager.runSync(
+ <String>[
+ flutterBin,
+ ...getLocalEngineArguments(),
+ 'create',
+ '--template=plugin',
+ '--platforms=android',
+ 'bbb',
+ '-v',
+ ],
+ workingDirectory: tempDir.path,
+ );
});
tearDown(() async {
@@ -48,14 +52,17 @@
// Ensure file is gone prior to configOnly running.
await gradleFile.delete();
- final ProcessResult result = processManager.runSync(<String>[
- flutterBin,
- ...getLocalEngineArguments(),
- 'build',
- 'apk',
- '--target-platform=android-arm',
- '--config-only',
- ], workingDirectory: exampleAppDir.path);
+ final ProcessResult result = processManager.runSync(
+ <String>[
+ flutterBin,
+ ...getLocalEngineArguments(),
+ 'build',
+ 'apk',
+ '--target-platform=android-arm',
+ '--config-only',
+ ],
+ workingDirectory: exampleAppDir.path,
+ );
expect(gradleFile, exists);
expect(result.stdout, contains(RegExp(r'Config complete')));
diff --git a/packages/flutter_tools/test/integration.shard/flutter_build_wasm_test.dart b/packages/flutter_tools/test/integration.shard/flutter_build_wasm_test.dart
index 593aeb3..4290db3 100644
--- a/packages/flutter_tools/test/integration.shard/flutter_build_wasm_test.dart
+++ b/packages/flutter_tools/test/integration.shard/flutter_build_wasm_test.dart
@@ -46,7 +46,7 @@
flutterWebWasm.environmentOverride!: 'true'
},
);
- expect(result.exitCode, 0);
+ expect(result, const ProcessResultMatcher());
final Directory appBuildDir = fileSystem.directory(fileSystem.path.join(
exampleAppDir.path,
diff --git a/packages/flutter_tools/test/integration.shard/flutter_build_windows_test.dart b/packages/flutter_tools/test/integration.shard/flutter_build_windows_test.dart
index 8311419..c90a940 100644
--- a/packages/flutter_tools/test/integration.shard/flutter_build_windows_test.dart
+++ b/packages/flutter_tools/test/integration.shard/flutter_build_windows_test.dart
@@ -26,16 +26,18 @@
'bin',
'flutter',
);
- processManager.runSync(<String>[flutterBin, 'config',
+ ProcessResult result = processManager.runSync(<String>[flutterBin, 'config',
'--enable-windows-desktop',
]);
+ expect(result, const ProcessResultMatcher());
- processManager.runSync(<String>[
+ result = processManager.runSync(<String>[
flutterBin,
...getLocalEngineArguments(),
'create',
'hello',
], workingDirectory: tempDir.path);
+ expect(result, const ProcessResultMatcher());
projectRoot = tempDir.childDirectory('hello');
@@ -65,8 +67,8 @@
'windows',
'--no-pub',
], workingDirectory: projectRoot.path);
+ expect(result, const ProcessResultMatcher());
- expect(result.exitCode, 0);
expect(releaseDir, exists);
expect(exeFile, exists);
@@ -79,7 +81,7 @@
});
testWithoutContext('flutter build windows sets build name', () {
- processManager.runSync(<String>[
+ final ProcessResult result = processManager.runSync(<String>[
flutterBin,
...getLocalEngineArguments(),
'build',
@@ -88,6 +90,7 @@
'--build-name',
'1.2.3',
], workingDirectory: projectRoot.path);
+ expect(result, const ProcessResultMatcher());
final String fileVersion = _getFileVersion(exeFile);
final String productVersion = _getProductVersion(exeFile);
@@ -97,7 +100,7 @@
});
testWithoutContext('flutter build windows sets build name and build number', () {
- processManager.runSync(<String>[
+ final ProcessResult result = processManager.runSync(<String>[
flutterBin,
...getLocalEngineArguments(),
'build',
@@ -108,6 +111,7 @@
'--build-number',
'4',
], workingDirectory: projectRoot.path);
+ expect(result, const ProcessResultMatcher());
final String fileVersion = _getFileVersion(exeFile);
final String productVersion = _getProductVersion(exeFile);
@@ -129,9 +133,7 @@
<String>[]
);
- if (result.exitCode != 0) {
- throw Exception('GetVersionInfo failed.');
- }
+ expect(result, const ProcessResultMatcher());
// Trim trailing new line.
final String output = result.stdout as String;
@@ -144,9 +146,7 @@
<String>[]
);
- if (result.exitCode != 0) {
- throw Exception('GetVersionInfo failed.');
- }
+ expect(result, const ProcessResultMatcher());
// Trim trailing new line.
final String output = result.stdout as String;
diff --git a/packages/flutter_tools/test/integration.shard/flutter_build_with_compilation_error_test.dart b/packages/flutter_tools/test/integration.shard/flutter_build_with_compilation_error_test.dart
index fa99726..36d15e9 100644
--- a/packages/flutter_tools/test/integration.shard/flutter_build_with_compilation_error_test.dart
+++ b/packages/flutter_tools/test/integration.shard/flutter_build_with_compilation_error_test.dart
@@ -64,11 +64,13 @@
], workingDirectory: projectRoot.path);
expect(
- result.stderr,
- contains("A value of type 'String' can't be assigned to a variable of type 'int'."),
+ result,
+ const ProcessResultMatcher(
+ exitCode: 1,
+ stderrPattern: "A value of type 'String' can't be assigned to a variable of type 'int'.",
+ ),
);
expect(result.stderr, isNot(contains("Warning: The 'dart2js' entrypoint script is deprecated")));
- expect(result.exitCode, 1);
});
}
}
diff --git a/packages/flutter_tools/test/integration.shard/gen_l10n_test.dart b/packages/flutter_tools/test/integration.shard/gen_l10n_test.dart
index 6827b38..13be650 100644
--- a/packages/flutter_tools/test/integration.shard/gen_l10n_test.dart
+++ b/packages/flutter_tools/test/integration.shard/gen_l10n_test.dart
@@ -126,46 +126,49 @@
'#l10n 73 (he)\n'
'#l10n 74 (they)\n'
'#l10n 75 (she)\n'
- '#l10n 76 (--- es ---)\n'
- '#l10n 77 (ES - Hello world)\n'
- '#l10n 78 (ES - Hello _NEWLINE_ World)\n'
- '#l10n 79 (ES - Hola \$ Mundo)\n'
- '#l10n 80 (ES - Hello Mundo)\n'
- '#l10n 81 (ES - Hola Mundo)\n'
- '#l10n 82 (ES - Hello World on viernes, 1 de enero de 1960)\n'
- '#l10n 83 (ES - Hello world argument on 1/1/1960 at 0:00)\n'
- '#l10n 84 (ES - Hello World from 1960 to 2020)\n'
- '#l10n 85 (ES - Hello for 123)\n'
- '#l10n 86 (ES - Hello)\n'
- '#l10n 87 (ES - Hello World)\n'
- '#l10n 88 (ES - Hello two worlds)\n'
- '#l10n 89 (ES - Hello)\n'
- '#l10n 90 (ES - Hello nuevo World)\n'
- '#l10n 91 (ES - Hello two nuevo worlds)\n'
- '#l10n 92 (ES - Hello on viernes, 1 de enero de 1960)\n'
- '#l10n 93 (ES - Hello World, on viernes, 1 de enero de 1960)\n'
- '#l10n 94 (ES - Hello two worlds, on viernes, 1 de enero de 1960)\n'
- '#l10n 95 (ES - Hello other 0 worlds, with a total of 100 citizens)\n'
- '#l10n 96 (ES - Hello World of 101 citizens)\n'
- '#l10n 97 (ES - Hello two worlds with 102 total citizens)\n'
- '#l10n 98 (ES - [Hola] -Mundo- #123#)\n'
- '#l10n 99 (ES - \$!)\n'
- '#l10n 100 (ES - One \$)\n'
- "#l10n 101 (ES - Flutter's amazing!)\n"
- "#l10n 102 (ES - Flutter's amazing, times 2!)\n"
- '#l10n 103 (ES - Flutter is "amazing"!)\n'
- '#l10n 104 (ES - Flutter is "amazing", times 2!)\n'
- '#l10n 105 (ES - 16 wheel truck)\n'
- "#l10n 106 (ES - Sedan's elegance)\n"
- '#l10n 107 (ES - Cabriolet has "acceleration")\n'
- '#l10n 108 (ES - Oh, she found ES - 1 itemES - !)\n'
- '#l10n 109 (ES - Indeed, ES - they like ES - Flutter!)\n'
- '#l10n 110 (--- es_419 ---)\n'
- '#l10n 111 (ES 419 - Hello World)\n'
- '#l10n 112 (ES 419 - Hello)\n'
+ '#l10n 76 (6/26/2023)\n'
+ '#l10n 77 (5:23:00 AM)\n'
+ '#l10n 78 (--- es ---)\n'
+ '#l10n 79 (ES - Hello world)\n'
+ '#l10n 80 (ES - Hello _NEWLINE_ World)\n'
+ '#l10n 81 (ES - Hola \$ Mundo)\n'
+ '#l10n 82 (ES - Hello Mundo)\n'
+ '#l10n 83 (ES - Hola Mundo)\n'
+ '#l10n 84 (ES - Hello World on viernes, 1 de enero de 1960)\n'
+ '#l10n 85 (ES - Hello world argument on 1/1/1960 at 0:00)\n'
+ '#l10n 86 (ES - Hello World from 1960 to 2020)\n'
+ '#l10n 87 (ES - Hello for 123)\n'
+ '#l10n 88 (ES - Hello)\n'
+ '#l10n 89 (ES - Hello World)\n'
+ '#l10n 90 (ES - Hello two worlds)\n'
+ '#l10n 91 (ES - Hello)\n'
+ '#l10n 92 (ES - Hello nuevo World)\n'
+ '#l10n 93 (ES - Hello two nuevo worlds)\n'
+ '#l10n 94 (ES - Hello on viernes, 1 de enero de 1960)\n'
+ '#l10n 95 (ES - Hello World, on viernes, 1 de enero de 1960)\n'
+ '#l10n 96 (ES - Hello two worlds, on viernes, 1 de enero de 1960)\n'
+ '#l10n 97 (ES - Hello other 0 worlds, with a total of 100 citizens)\n'
+ '#l10n 98 (ES - Hello World of 101 citizens)\n'
+ '#l10n 99 (ES - Hello two worlds with 102 total citizens)\n'
+ '#l10n 100 (ES - [Hola] -Mundo- #123#)\n'
+ '#l10n 101 (ES - \$!)\n'
+ '#l10n 102 (ES - One \$)\n'
+ "#l10n 103 (ES - Flutter's amazing!)\n"
+ "#l10n 104 (ES - Flutter's amazing, times 2!)\n"
+ '#l10n 105 (ES - Flutter is "amazing"!)\n'
+ '#l10n 106 (ES - Flutter is "amazing", times 2!)\n'
+ '#l10n 107 (ES - 16 wheel truck)\n'
+ "#l10n 108 (ES - Sedan's elegance)\n"
+ '#l10n 109 (ES - Cabriolet has "acceleration")\n'
+ '#l10n 110 (ES - Oh, she found ES - 1 itemES - !)\n'
+ '#l10n 111 (ES - Indeed, ES - they like ES - Flutter!)\n'
+ '#l10n 112 (--- es_419 ---)\n'
'#l10n 113 (ES 419 - Hello World)\n'
- '#l10n 114 (ES 419 - Hello two worlds)\n'
+ '#l10n 114 (ES 419 - Hello)\n'
+ '#l10n 115 (ES 419 - Hello World)\n'
+ '#l10n 116 (ES 419 - Hello two worlds)\n'
'#l10n END\n'
+
);
}
diff --git a/packages/flutter_tools/test/integration.shard/test_data/gen_l10n_project.dart b/packages/flutter_tools/test/integration.shard/test_data/gen_l10n_project.dart
index 46d2a51..68cc153 100644
--- a/packages/flutter_tools/test/integration.shard/test_data/gen_l10n_project.dart
+++ b/packages/flutter_tools/test/integration.shard/test_data/gen_l10n_project.dart
@@ -232,6 +232,8 @@
"${localizations.selectInPlural('male', 1)}",
"${localizations.selectInPlural('male', 2)}",
"${localizations.selectInPlural('female', 1)}",
+ '${localizations.datetime1(DateTime(2023, 6, 26))}',
+ '${localizations.datetime2(DateTime(2023, 6, 26, 5, 23))}',
]);
},
),
@@ -682,7 +684,9 @@
"type": "num"
}
}
- }
+ },
+ "datetime1": "{today, date, ::yMd}",
+ "datetime2": "{current, time, ::jms}"
}
''';
diff --git a/packages/flutter_tools/test/integration.shard/test_test.dart b/packages/flutter_tools/test/integration.shard/test_test.dart
index a5979e3..86e0d11 100644
--- a/packages/flutter_tools/test/integration.shard/test_test.dart
+++ b/packages/flutter_tools/test/integration.shard/test_test.dart
@@ -235,7 +235,7 @@
if ((result.stderr as String).isNotEmpty) {
fail('unexpected error output from test:\n\n${result.stderr}\n-- end stderr --\n\n');
}
- expect(result.exitCode, 0);
+ expect(result, const ProcessResultMatcher());
});
testWithoutContext('flutter test should run all tests inside of a directory with no trailing slash', () async {
@@ -250,7 +250,7 @@
if ((result.stderr as String).isNotEmpty) {
fail('unexpected error output from test:\n\n${result.stderr}\n-- end stderr --\n\n');
}
- expect(result.exitCode, 0);
+ expect(result, const ProcessResultMatcher());
});
testWithoutContext('flutter gold skips tests where the expectations are missing', () async {
diff --git a/packages/flutter_tools/test/integration.shard/xcode_backend_test.dart b/packages/flutter_tools/test/integration.shard/xcode_backend_test.dart
index 36cfa61..d34d242 100644
--- a/packages/flutter_tools/test/integration.shard/xcode_backend_test.dart
+++ b/packages/flutter_tools/test/integration.shard/xcode_backend_test.dart
@@ -9,6 +9,7 @@
import 'package:flutter_tools/src/globals.dart' as globals;
import '../src/common.dart';
+import 'test_utils.dart';
const String xcodeBackendPath = 'bin/xcode_backend.sh';
const String xcodeBackendErrorHeader = '========================================================================';
@@ -85,8 +86,7 @@
'INFOPLIST_PATH': 'Info.plist',
},
);
- expect(result.stdout, contains('Info.plist does not exist.'));
- expect(result.exitCode, 0);
+ expect(result, const ProcessResultMatcher(stdoutPattern: 'Info.plist does not exist.'));
});
const String emptyPlist = '''
@@ -115,7 +115,7 @@
expect(actualInfoPlist, isNot(contains('dartVmService')));
expect(actualInfoPlist, isNot(contains('NSLocalNetworkUsageDescription')));
- expect(result.exitCode, 0);
+ expect(result, const ProcessResultMatcher());
});
for (final String buildConfiguration in <String>['Debug', 'Profile']) {
@@ -137,7 +137,7 @@
expect(actualInfoPlist, contains('dartVmService'));
expect(actualInfoPlist, contains('NSLocalNetworkUsageDescription'));
- expect(result.exitCode, 0);
+ expect(result, const ProcessResultMatcher());
});
}
@@ -181,7 +181,7 @@
</dict>
</plist>
''');
- expect(result.exitCode, 0);
+ expect(result, const ProcessResultMatcher());
});
}, skip: !io.Platform.isMacOS); // [intended] requires macos toolchain.
}
diff --git a/packages/flutter_tools/test/src/fakes.dart b/packages/flutter_tools/test/src/fakes.dart
index b7c5856..65fb557 100644
--- a/packages/flutter_tools/test/src/fakes.dart
+++ b/packages/flutter_tools/test/src/fakes.dart
@@ -13,6 +13,7 @@
import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/os.dart';
+import 'package:flutter_tools/src/base/time.dart';
import 'package:flutter_tools/src/base/version.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/convert.dart';
@@ -337,6 +338,8 @@
this.frameworkAge = '0 hours ago',
this.frameworkCommitDate = '12/01/01',
this.gitTagVersion = const GitTagVersion.unknown(),
+ this.flutterRoot = '/path/to/flutter',
+ this.nextFlutterVersion,
});
final String branch;
@@ -344,6 +347,17 @@
bool get didFetchTagsAndUpdate => _didFetchTagsAndUpdate;
bool _didFetchTagsAndUpdate = false;
+ /// Will be returned by [fetchTagsAndGetVersion] if not null.
+ final FlutterVersion? nextFlutterVersion;
+
+ @override
+ FlutterVersion fetchTagsAndGetVersion({
+ SystemClock clock = const SystemClock(),
+ }) {
+ _didFetchTagsAndUpdate = true;
+ return nextFlutterVersion ?? this;
+ }
+
bool get didCheckFlutterVersionFreshness => _didCheckFlutterVersionFreshness;
bool _didCheckFlutterVersionFreshness = false;
@@ -356,6 +370,9 @@
}
@override
+ final String flutterRoot;
+
+ @override
final String devToolsVersion;
@override
@@ -386,15 +403,10 @@
final String frameworkCommitDate;
@override
- String get frameworkDate => frameworkCommitDate;
-
- @override
final GitTagVersion gitTagVersion;
@override
- void fetchTagsAndUpdate() {
- _didFetchTagsAndUpdate = true;
- }
+ FileSystem get fs => throw UnimplementedError('FakeFlutterVersion.fs is not implemented');
@override
Future<void> checkFlutterVersionFreshness() async {
diff --git a/packages/flutter_web_plugins/pubspec.yaml b/packages/flutter_web_plugins/pubspec.yaml
index 16368f2..d5efee9 100644
--- a/packages/flutter_web_plugins/pubspec.yaml
+++ b/packages/flutter_web_plugins/pubspec.yaml
@@ -11,10 +11,10 @@
characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
collection: 1.17.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.9.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
flutter_test:
@@ -27,10 +27,10 @@
matcher: 0.12.16 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path: 1.8.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
-# PUBSPEC CHECKSUM: d91e
+# PUBSPEC CHECKSUM: 7f45
diff --git a/packages/fuchsia_remote_debug_protocol/pubspec.yaml b/packages/fuchsia_remote_debug_protocol/pubspec.yaml
index 11b69e1..b02d256 100644
--- a/packages/fuchsia_remote_debug_protocol/pubspec.yaml
+++ b/packages/fuchsia_remote_debug_protocol/pubspec.yaml
@@ -8,7 +8,7 @@
dependencies:
process: 4.2.4
- vm_service: 11.6.0
+ vm_service: 11.7.2
file: 6.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.9.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -16,10 +16,10 @@
platform: 3.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
- test: 1.24.3
+ test: 1.24.4
- _fe_analyzer_shared: 61.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- analyzer: 5.13.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ _fe_analyzer_shared: 62.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ analyzer: 6.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
args: 2.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
async: 2.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -27,6 +27,7 @@
convert: 3.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
coverage: 1.6.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
crypto: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ dart_internal: 0.2.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
frontend_server_client: 3.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
glob: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http_multi_server: 3.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -47,12 +48,12 @@
source_map_stack_trace: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_maps: 0.10.12 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_core: 0.5.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_core: 0.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -63,4 +64,4 @@
# Exclude this package from the hosted API docs.
nodoc: true
-# PUBSPEC CHECKSUM: a47e
+# PUBSPEC CHECKSUM: 4a12
diff --git a/packages/integration_test/analysis_options.yaml b/packages/integration_test/analysis_options.yaml
new file mode 100644
index 0000000..e61f982
--- /dev/null
+++ b/packages/integration_test/analysis_options.yaml
@@ -0,0 +1,5 @@
+include: ../analysis_options.yaml
+
+analyzer:
+ exclude:
+ - "test_fixes/**"
diff --git a/packages/integration_test/example/ios/Runner/Info.plist b/packages/integration_test/example/ios/Runner/Info.plist
index 46c572f..c624d4e 100644
--- a/packages/integration_test/example/ios/Runner/Info.plist
+++ b/packages/integration_test/example/ios/Runner/Info.plist
@@ -39,8 +39,6 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
- <key>UIViewControllerBasedStatusBarAppearance</key>
- <false/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
diff --git a/packages/integration_test/example/pubspec.yaml b/packages/integration_test/example/pubspec.yaml
index df1a1e6..754a3cd 100644
--- a/packages/integration_test/example/pubspec.yaml
+++ b/packages/integration_test/example/pubspec.yaml
@@ -14,10 +14,10 @@
characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
collection: 1.17.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.9.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
flutter_test:
@@ -28,14 +28,14 @@
sdk: flutter
integration_test_macos:
path: ../integration_test_macos
- test: 1.24.3
+ test: 1.24.4
pedantic: 1.11.1
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
- _fe_analyzer_shared: 61.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- analyzer: 5.13.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ _fe_analyzer_shared: 62.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ analyzer: 6.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
args: 2.4.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
async: 2.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -43,6 +43,7 @@
convert: 3.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
coverage: 1.6.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
crypto: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ dart_internal: 0.2.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
fake_async: 1.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
file: 6.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
frontend_server_client: 3.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -50,6 +51,7 @@
http_multi_server: 3.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http_parser: 4.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
io: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
logging: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
matcher: 0.12.16 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
mime: 1.0.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -65,15 +67,15 @@
source_map_stack_trace: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_maps: 0.10.12 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
sync_http: 0.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_core: 0.5.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_core: 0.5.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- vm_service: 11.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ vm_service: 11.7.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 2.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -83,4 +85,4 @@
flutter:
uses-material-design: true
-# PUBSPEC CHECKSUM: 39a4
+# PUBSPEC CHECKSUM: 108e
diff --git a/packages/integration_test/integration_test_macos/pubspec.yaml b/packages/integration_test/integration_test_macos/pubspec.yaml
index 800067e..5628fc1 100644
--- a/packages/integration_test/integration_test_macos/pubspec.yaml
+++ b/packages/integration_test/integration_test_macos/pubspec.yaml
@@ -18,12 +18,12 @@
characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
collection: 1.17.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.9.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
pedantic: 1.11.1
-# PUBSPEC CHECKSUM: d263
+# PUBSPEC CHECKSUM: 4387
diff --git a/packages/integration_test/lib/fix_data/README.md b/packages/integration_test/lib/fix_data/README.md
new file mode 100644
index 0000000..748818f
--- /dev/null
+++ b/packages/integration_test/lib/fix_data/README.md
@@ -0,0 +1,45 @@
+## Directory contents
+
+The `.yaml` files in these directories are used to
+define the [`dart fix` framework](https://dart.dev/tools/dart-fix) refactorings
+used by `integration_test`.
+
+The number of fix rules defined in a file should not exceed 50 for better
+maintainability. Searching for `title:` in a given `.yaml` file will account
+for the number of fixes. Splitting out fix rules should be done by class.
+
+When adding a new `.yaml` file, make a copy of `template.yaml`. Each file should
+be for a single class and named `fix_<class>.yaml`. To make sure each file is
+grouped with related classes, a `fix_<filename>` folder will contain all of the
+fix files for the individual classes.
+
+See the flutter/packages/integration_test/test_fixes directory for the tests
+that validate these fix rules.
+
+To run these tests locally, execute this command in the
+flutter/packages/integration_test/test_fixes directory.
+```sh
+dart fix --compare-to-golden
+```
+
+For more documentation about Data Driven Fixes, see
+https://dart.dev/go/data-driven-fixes#test-folder.
+
+To learn more about how fixes are authored in package:integration_test, see
+https://github.com/flutter/flutter/wiki/Data-driven-Fixes
+
+## When making structural changes to this directory
+
+The tests in this directory are also invoked from external
+repositories. Specifically, the CI system for the dart-lang/sdk repo
+runs these tests in order to ensure that changes to the dart fix file
+format do not break Flutter.
+
+See [tools/bots/flutter/analyze_flutter_flutter.sh](https://github.com/dart-lang/sdk/blob/main/tools/bots/flutter/analyze_flutter_flutter.sh)
+for where the flutter fix tests are invoked for the dart repo.
+
+See [dev/bots/test.dart](https://github.com/flutter/flutter/blob/master/dev/bots/test.dart)
+for where the flutter fix tests are invoked for the flutter/flutter repo.
+
+When possible, please coordinate changes to this directory that might affect the
+`analyze_flutter_flutter.sh` script.
diff --git a/packages/integration_test/lib/fix_data/fix_integration_test/fix_binding/fix_integration_test_widgets_flutter_binding.yaml b/packages/integration_test/lib/fix_data/fix_integration_test/fix_binding/fix_integration_test_widgets_flutter_binding.yaml
new file mode 100644
index 0000000..2609269
--- /dev/null
+++ b/packages/integration_test/lib/fix_data/fix_integration_test/fix_binding/fix_integration_test_widgets_flutter_binding.yaml
@@ -0,0 +1,33 @@
+# Copyright 2014 The Flutter Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# For details regarding the *Flutter Fix* feature, see
+# https://flutter.dev/docs/development/tools/flutter-fix
+
+# Please add new fixes to the top of the file, separated by one blank line
+# from other fixes. In a comment, include a link to the PR where the change
+# requiring the fix was made.
+
+# Every fix must be tested. See the
+# flutter/packages/integration_test/test_fixes/README.md file for instructions
+# on testing these data driven fixes.
+
+# For documentation about this file format, see
+# https://dart.dev/go/data-driven-fixes.
+
+# * Fixes in this file are for IntegrationTestWidgetsFlutterBinding from the
+# integration_test/integration_test.dart file. *
+
+version: 1
+transforms:
+ # Changes made in https://github.com/flutter/flutter/pull/89952
+ - title: "Remove timeout"
+ date: 2023-06-26
+ element:
+ uris: [ 'integration_test.dart' ]
+ method: 'runTest'
+ inClass: 'IntegrationTestWidgetsFlutterBinding'
+ changes:
+ - kind: 'removeParameter'
+ name: 'timeout'
diff --git a/packages/integration_test/lib/fix_data/template.yaml b/packages/integration_test/lib/fix_data/template.yaml
new file mode 100644
index 0000000..27c5d14
--- /dev/null
+++ b/packages/integration_test/lib/fix_data/template.yaml
@@ -0,0 +1,25 @@
+# Copyright 2014 The Flutter Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# For details regarding the *Flutter Fix* feature, see
+# https://flutter.dev/docs/development/tools/flutter-fix
+
+# Please add new fixes to the top of the file, separated by one blank line
+# from other fixes. In a comment, include a link to the PR where the change
+# requiring the fix was made.
+
+# Every fix must be tested. See the
+# flutter/packages/integration_test/lib/fix_data/README.md file for instructions
+# on testing these data driven fixes.
+
+# For documentation about this file format, see
+# https://dart.dev/go/data-driven-fixes.
+
+# * Fixes in this file are [for CLASS] from the <XXX> file. *
+
+# Uncomment version & transforms, and follow with fixes.
+# version: 1
+# transforms:
+
+# Before adding a new fix: read instructions at the top of this file.
diff --git a/packages/integration_test/pubspec.yaml b/packages/integration_test/pubspec.yaml
index f27853a..9206b04 100644
--- a/packages/integration_test/pubspec.yaml
+++ b/packages/integration_test/pubspec.yaml
@@ -13,7 +13,7 @@
flutter_test:
sdk: flutter
path: 1.8.3
- vm_service: 11.6.0
+ vm_service: 11.7.2
async: 2.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -22,18 +22,18 @@
collection: 1.17.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
fake_async: 1.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
file: 6.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
matcher: 0.12.16 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
material_color_utilities: 0.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta: 1.9.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stack_trace: 1.11.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ stream_channel: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
sync_http: 0.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- test_api: 0.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ test_api: 0.6.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ web: 0.1.4-beta # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
flutter:
@@ -45,4 +45,4 @@
ios:
pluginClass: IntegrationTestPlugin
-# PUBSPEC CHECKSUM: bb0e
+# PUBSPEC CHECKSUM: 4738
diff --git a/packages/integration_test/test_fixes/.dartignore b/packages/integration_test/test_fixes/.dartignore
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/packages/integration_test/test_fixes/.dartignore
diff --git a/packages/integration_test/test_fixes/analysis_options.yaml b/packages/integration_test/test_fixes/analysis_options.yaml
new file mode 100644
index 0000000..7cca7b1
--- /dev/null
+++ b/packages/integration_test/test_fixes/analysis_options.yaml
@@ -0,0 +1 @@
+# This ensures that parent analysis options do not accidentally break the fix tests.
diff --git a/packages/integration_test/test_fixes/integration_test/binding/integration_test_widgets_flutter_binding.dart b/packages/integration_test/test_fixes/integration_test/binding/integration_test_widgets_flutter_binding.dart
new file mode 100644
index 0000000..2360cec
--- /dev/null
+++ b/packages/integration_test/test_fixes/integration_test/binding/integration_test_widgets_flutter_binding.dart
@@ -0,0 +1,15 @@
+// Copyright 2014 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'package:integration_test/integration_test.dart';
+
+void main() {
+ final binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized();
+ binding.runTest(
+ () async { },
+ () { },
+ // Changes made in https://github.com/flutter/flutter/pull/89952
+ timeout: Duration(minutes: 30),
+ );
+}
diff --git a/packages/integration_test/test_fixes/integration_test/binding/integration_test_widgets_flutter_binding.dart.expect b/packages/integration_test/test_fixes/integration_test/binding/integration_test_widgets_flutter_binding.dart.expect
new file mode 100644
index 0000000..8abee15
--- /dev/null
+++ b/packages/integration_test/test_fixes/integration_test/binding/integration_test_widgets_flutter_binding.dart.expect
@@ -0,0 +1,13 @@
+// Copyright 2014 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'package:integration_test/integration_test.dart';
+
+void main() {
+ final binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized();
+ binding.runTest(
+ () async { },
+ () { },
+ );
+}