diff --git a/.ci.yaml b/.ci.yaml
index 2d0db05cd45f..57bfec26fd90 100644
--- a/.ci.yaml
+++ b/.ci.yaml
@@ -24,27 +24,37 @@ platform_properties:
properties:
dependencies: >-
[
- {"dependency": "xcode", "version": "14c18"},
+ {"dependency": "xcode", "version": "14e222b"},
{"dependency": "gems", "version": "v3.3.14"}
]
os: Mac-12
device_type: none
cpu: arm64
- xcode: 14c18
+ xcode: 14e222b
mac_x64:
properties:
dependencies: >-
[
- {"dependency": "xcode", "version": "14c18"},
+ {"dependency": "xcode", "version": "14e222b"},
{"dependency": "gems", "version": "v3.3.14"}
]
os: Mac-12
device_type: none
cpu: x86
- xcode: 14c18
+ xcode: 14e222b
targets:
- ### iOS+macOS tasks ***
+ ### Linux tasks ###
+ - name: Linux repo_tools_tests
+ recipe: packages/packages
+ timeout: 30
+ properties:
+ add_recipes_cq: "true"
+ target_file: repo_tools_tests.yaml
+ channel: master
+ version_file: flutter_master.version
+
+ ### iOS+macOS tasks ###
# TODO(stuartmorgan): Move this to ARM once google_maps_flutter has ARM
# support. `pod lint` makes a synthetic target that doesn't respect the
# pod's arch exclusions, so fails to build.
@@ -139,12 +149,9 @@ targets:
version_file: flutter_stable.version
target_file: ios_build_all_packages.yaml
- # TODO(stuartmorgan): Change all of the ios_platform_tests_* task timeouts
- # to 60 minutes once https://github.com/flutter/flutter/issues/119750 is
- # fixed.
- name: Mac_arm64 ios_platform_tests_shard_1 master
recipe: packages/packages
- timeout: 120
+ timeout: 60
properties:
add_recipes_cq: "true"
version_file: flutter_master.version
@@ -153,7 +160,7 @@ targets:
- name: Mac_arm64 ios_platform_tests_shard_2 master
recipe: packages/packages
- timeout: 120
+ timeout: 60
properties:
add_recipes_cq: "true"
version_file: flutter_master.version
@@ -162,7 +169,7 @@ targets:
- name: Mac_arm64 ios_platform_tests_shard_3 master
recipe: packages/packages
- timeout: 120
+ timeout: 60
properties:
add_recipes_cq: "true"
version_file: flutter_master.version
@@ -171,7 +178,7 @@ targets:
- name: Mac_arm64 ios_platform_tests_shard_4 master
recipe: packages/packages
- timeout: 120
+ timeout: 60
properties:
add_recipes_cq: "true"
version_file: flutter_master.version
@@ -180,7 +187,7 @@ targets:
- name: Mac_arm64 ios_platform_tests_shard_5 master
recipe: packages/packages
- timeout: 120
+ timeout: 60
properties:
add_recipes_cq: "true"
version_file: flutter_master.version
@@ -191,7 +198,7 @@ targets:
- name: Mac_arm64 ios_platform_tests_shard_1 stable
recipe: packages/packages
presubmit: false
- timeout: 120
+ timeout: 60
properties:
channel: stable
add_recipes_cq: "true"
@@ -202,7 +209,7 @@ targets:
- name: Mac_arm64 ios_platform_tests_shard_2 stable
recipe: packages/packages
presubmit: false
- timeout: 120
+ timeout: 60
properties:
channel: stable
add_recipes_cq: "true"
@@ -213,7 +220,7 @@ targets:
- name: Mac_arm64 ios_platform_tests_shard_3 stable
recipe: packages/packages
presubmit: false
- timeout: 120
+ timeout: 60
properties:
channel: stable
add_recipes_cq: "true"
@@ -224,7 +231,7 @@ targets:
- name: Mac_arm64 ios_platform_tests_shard_4 stable
recipe: packages/packages
presubmit: false
- timeout: 120
+ timeout: 60
properties:
channel: stable
add_recipes_cq: "true"
@@ -235,7 +242,7 @@ targets:
- name: Mac_arm64 ios_platform_tests_shard_5 stable
recipe: packages/packages
presubmit: false
- timeout: 120
+ timeout: 60
properties:
channel: stable
add_recipes_cq: "true"
diff --git a/.ci/Dockerfile b/.ci/Dockerfile
index 224b9d72de9e..d1ddf61c9218 100644
--- a/.ci/Dockerfile
+++ b/.ci/Dockerfile
@@ -23,7 +23,7 @@ RUN apt-get install -y clang-format
# - build tools.
RUN apt-get install -y clang cmake ninja-build file pkg-config
# - libraries.
-RUN apt-get install -y libgtk-3-dev libblkid-dev liblzma-dev libgcrypt20-dev
+RUN apt-get install -y libgtk-3-dev
# - xvfb to allow running headless.
RUN apt-get install -y xvfb libegl1-mesa
diff --git a/.ci/flutter_master.version b/.ci/flutter_master.version
index 7ad6ea501624..b837ee2e4915 100644
--- a/.ci/flutter_master.version
+++ b/.ci/flutter_master.version
@@ -1 +1 @@
-66fa4c5d301c5093cb4403b39e3d61f604b96d90
+343718945bcbcc356dbb8b1c51fcd5655dd5bb87
diff --git a/.ci/flutter_stable.version b/.ci/flutter_stable.version
index f88f99fd4646..4e463678673b 100644
--- a/.ci/flutter_stable.version
+++ b/.ci/flutter_stable.version
@@ -1 +1 @@
-f72efea43c3013323d1b95cff571f3c1caa37583
+d3d8effc686d73e0114d71abdcccef63fa1f25d2
diff --git a/.ci/legacy_project/README.md b/.ci/legacy_project/README.md
new file mode 100644
index 000000000000..c10ace0b2c2d
--- /dev/null
+++ b/.ci/legacy_project/README.md
@@ -0,0 +1,37 @@
+This directory contains a partial snapshot of an old Flutter project; it is
+intended to replace the corresponding parts of a newly Flutter-created project
+to allow testing plugin builds with a legacy project.
+
+It was originally created with Flutter 2.0.6. In general the guidelines are:
+- Pieces here should be largely self-contained rather than portions of
+ major project components; for instance, it currently contains the entire
+ `android/` directory from a legacy project, rather than a subset of it
+ which would be combined with a subset of a new project's `android/`
+ directory. This is to avoid random breakage in the future due to
+ conflicts between those subsets. For instance, we could probably get
+ away with not including android/app/src/main/res for a while, and
+ instead layer in the versions from a new project, but then someday
+ if the resources were renamed, there would be dangling references to
+ the old resources in files that are included here.
+- Updates over time should be minimal. We don't expect that an unchanged
+ project will keep working forever, but this directory should simulate
+ a developer who has done the bare minimum to keep their project working
+ as they have updated Flutter.
+- Updates should be logged below.
+
+The reason for the hybrid model, rather than checking in a full legacy
+project, is to minimize unnecessary maintenance work. E.g., there's no
+need to manually keep Dart code updated for Flutter changes just to
+test legacy native Android build behaviors.
+
+## Manual changes to files
+
+The following are the changes relative to running:
+
+```bash
+flutter create -a java all_packages
+```
+
+and then deleting everything but `android/` from it:
+
+- Added license boilerplate.
diff --git a/.ci/legacy_project/all_packages/.gitignore b/.ci/legacy_project/all_packages/.gitignore
new file mode 100644
index 000000000000..0fa6b675c0a5
--- /dev/null
+++ b/.ci/legacy_project/all_packages/.gitignore
@@ -0,0 +1,46 @@
+# Miscellaneous
+*.class
+*.log
+*.pyc
+*.swp
+.DS_Store
+.atom/
+.buildlog/
+.history
+.svn/
+
+# IntelliJ related
+*.iml
+*.ipr
+*.iws
+.idea/
+
+# The .vscode folder contains launch configuration and tasks you configure in
+# VS Code which you may wish to be included in version control, so this line
+# is commented out by default.
+#.vscode/
+
+# Flutter/Dart/Pub related
+**/doc/api/
+**/ios/Flutter/.last_build_id
+.dart_tool/
+.flutter-plugins
+.flutter-plugins-dependencies
+.packages
+.pub-cache/
+.pub/
+/build/
+
+# Web related
+lib/generated_plugin_registrant.dart
+
+# Symbolication related
+app.*.symbols
+
+# Obfuscation related
+app.*.map.json
+
+# Android Studio will place build artifacts here
+/android/app/debug
+/android/app/profile
+/android/app/release
diff --git a/.ci/legacy_project/all_packages/.metadata b/.ci/legacy_project/all_packages/.metadata
new file mode 100644
index 000000000000..d7e64d0b3225
--- /dev/null
+++ b/.ci/legacy_project/all_packages/.metadata
@@ -0,0 +1,10 @@
+# This file tracks properties of this Flutter project.
+# Used by Flutter tool to assess capabilities and perform upgrades etc.
+#
+# This file should be version controlled and should not be manually edited.
+
+version:
+ revision: 1d9032c7e1d867f071f2277eb1673e8f9b0274e3
+ channel: unknown
+
+project_type: app
diff --git a/.ci/legacy_project/all_packages/android/.gitignore b/.ci/legacy_project/all_packages/android/.gitignore
new file mode 100644
index 000000000000..0a741cb43d66
--- /dev/null
+++ b/.ci/legacy_project/all_packages/android/.gitignore
@@ -0,0 +1,11 @@
+gradle-wrapper.jar
+/.gradle
+/captures/
+/gradlew
+/gradlew.bat
+/local.properties
+GeneratedPluginRegistrant.java
+
+# Remember to never publicly share your keystore.
+# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
+key.properties
diff --git a/.ci/legacy_project/all_packages/android/app/build.gradle b/.ci/legacy_project/all_packages/android/app/build.gradle
new file mode 100644
index 000000000000..b75c7b0561bc
--- /dev/null
+++ b/.ci/legacy_project/all_packages/android/app/build.gradle
@@ -0,0 +1,47 @@
+def localProperties = new Properties()
+def localPropertiesFile = rootProject.file('local.properties')
+if (localPropertiesFile.exists()) {
+ localPropertiesFile.withReader('UTF-8') { reader ->
+ localProperties.load(reader)
+ }
+}
+
+def flutterRoot = localProperties.getProperty('flutter.sdk')
+if (flutterRoot == null) {
+ throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
+}
+
+def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
+if (flutterVersionCode == null) {
+ flutterVersionCode = '1'
+}
+
+def flutterVersionName = localProperties.getProperty('flutter.versionName')
+if (flutterVersionName == null) {
+ flutterVersionName = '1.0'
+}
+
+apply plugin: 'com.android.application'
+apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
+
+android {
+ compileSdkVersion 30
+
+ defaultConfig {
+ applicationId "com.example.all_packages"
+ minSdkVersion 16
+ targetSdkVersion 30
+ versionCode flutterVersionCode.toInteger()
+ versionName flutterVersionName
+ }
+
+ buildTypes {
+ release {
+ signingConfig signingConfigs.debug
+ }
+ }
+}
+
+flutter {
+ source '../..'
+}
diff --git a/.ci/legacy_project/all_packages/android/app/src/debug/AndroidManifest.xml b/.ci/legacy_project/all_packages/android/app/src/debug/AndroidManifest.xml
new file mode 100644
index 000000000000..3a38eba348d8
--- /dev/null
+++ b/.ci/legacy_project/all_packages/android/app/src/debug/AndroidManifest.xml
@@ -0,0 +1,4 @@
+
+
+
diff --git a/.ci/legacy_project/all_packages/android/app/src/main/AndroidManifest.xml b/.ci/legacy_project/all_packages/android/app/src/main/AndroidManifest.xml
new file mode 100644
index 000000000000..70c010f2867e
--- /dev/null
+++ b/.ci/legacy_project/all_packages/android/app/src/main/AndroidManifest.xml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.ci/legacy_project/all_packages/android/app/src/main/java/com/example/all_packages/MainActivity.java b/.ci/legacy_project/all_packages/android/app/src/main/java/com/example/all_packages/MainActivity.java
new file mode 100644
index 000000000000..f494afad857c
--- /dev/null
+++ b/.ci/legacy_project/all_packages/android/app/src/main/java/com/example/all_packages/MainActivity.java
@@ -0,0 +1,10 @@
+// Copyright 2013 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.
+
+package com.example.all_packages;
+
+import io.flutter.embedding.android.FlutterActivity;
+
+public class MainActivity extends FlutterActivity {
+}
diff --git a/.ci/legacy_project/all_packages/android/app/src/main/res/drawable-v21/launch_background.xml b/.ci/legacy_project/all_packages/android/app/src/main/res/drawable-v21/launch_background.xml
new file mode 100644
index 000000000000..f74085f3f6a2
--- /dev/null
+++ b/.ci/legacy_project/all_packages/android/app/src/main/res/drawable-v21/launch_background.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
diff --git a/.ci/legacy_project/all_packages/android/app/src/main/res/drawable/launch_background.xml b/.ci/legacy_project/all_packages/android/app/src/main/res/drawable/launch_background.xml
new file mode 100644
index 000000000000..304732f88420
--- /dev/null
+++ b/.ci/legacy_project/all_packages/android/app/src/main/res/drawable/launch_background.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
diff --git a/.ci/legacy_project/all_packages/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/.ci/legacy_project/all_packages/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 000000000000..db77bb4b7b09
Binary files /dev/null and b/.ci/legacy_project/all_packages/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/.ci/legacy_project/all_packages/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/.ci/legacy_project/all_packages/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 000000000000..17987b79bb8a
Binary files /dev/null and b/.ci/legacy_project/all_packages/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/.ci/legacy_project/all_packages/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/.ci/legacy_project/all_packages/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 000000000000..09d4391482be
Binary files /dev/null and b/.ci/legacy_project/all_packages/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/.ci/legacy_project/all_packages/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/.ci/legacy_project/all_packages/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 000000000000..d5f1c8d34e7a
Binary files /dev/null and b/.ci/legacy_project/all_packages/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/.ci/legacy_project/all_packages/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/.ci/legacy_project/all_packages/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 000000000000..4d6372eebdb2
Binary files /dev/null and b/.ci/legacy_project/all_packages/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/.ci/legacy_project/all_packages/android/app/src/main/res/values-night/styles.xml b/.ci/legacy_project/all_packages/android/app/src/main/res/values-night/styles.xml
new file mode 100644
index 000000000000..449a9f930826
--- /dev/null
+++ b/.ci/legacy_project/all_packages/android/app/src/main/res/values-night/styles.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
diff --git a/.ci/legacy_project/all_packages/android/app/src/main/res/values/styles.xml b/.ci/legacy_project/all_packages/android/app/src/main/res/values/styles.xml
new file mode 100644
index 000000000000..d74aa35c2826
--- /dev/null
+++ b/.ci/legacy_project/all_packages/android/app/src/main/res/values/styles.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
diff --git a/.ci/legacy_project/all_packages/android/app/src/profile/AndroidManifest.xml b/.ci/legacy_project/all_packages/android/app/src/profile/AndroidManifest.xml
new file mode 100644
index 000000000000..02ba522d3d9e
--- /dev/null
+++ b/.ci/legacy_project/all_packages/android/app/src/profile/AndroidManifest.xml
@@ -0,0 +1,7 @@
+
+
+
+
diff --git a/.ci/legacy_project/all_packages/android/build.gradle b/.ci/legacy_project/all_packages/android/build.gradle
new file mode 100644
index 000000000000..c9e3db0a0f33
--- /dev/null
+++ b/.ci/legacy_project/all_packages/android/build.gradle
@@ -0,0 +1,29 @@
+buildscript {
+ repositories {
+ google()
+ jcenter()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:4.1.0'
+ }
+}
+
+allprojects {
+ repositories {
+ google()
+ jcenter()
+ }
+}
+
+rootProject.buildDir = '../build'
+subprojects {
+ project.buildDir = "${rootProject.buildDir}/${project.name}"
+}
+subprojects {
+ project.evaluationDependsOn(':app')
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
diff --git a/.ci/legacy_project/all_packages/android/gradle.properties b/.ci/legacy_project/all_packages/android/gradle.properties
new file mode 100644
index 000000000000..94adc3a3f97a
--- /dev/null
+++ b/.ci/legacy_project/all_packages/android/gradle.properties
@@ -0,0 +1,3 @@
+org.gradle.jvmargs=-Xmx1536M
+android.useAndroidX=true
+android.enableJetifier=true
diff --git a/.ci/legacy_project/all_packages/android/gradle/wrapper/gradle-wrapper.properties b/.ci/legacy_project/all_packages/android/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 000000000000..bc6a58afdda2
--- /dev/null
+++ b/.ci/legacy_project/all_packages/android/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Fri Jun 23 08:50:38 CEST 2017
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
diff --git a/.ci/legacy_project/all_packages/android/settings.gradle b/.ci/legacy_project/all_packages/android/settings.gradle
new file mode 100644
index 000000000000..44e62bcf06ae
--- /dev/null
+++ b/.ci/legacy_project/all_packages/android/settings.gradle
@@ -0,0 +1,11 @@
+include ':app'
+
+def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
+def properties = new Properties()
+
+assert localPropertiesFile.exists()
+localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
+
+def flutterSdkPath = properties.getProperty("flutter.sdk")
+assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
+apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
diff --git a/.ci/scripts/build_all_packages_app.sh b/.ci/scripts/build_all_packages_app.sh
index c22b9832ff22..7b381acc4e9c 100755
--- a/.ci/scripts/build_all_packages_app.sh
+++ b/.ci/scripts/build_all_packages_app.sh
@@ -2,6 +2,7 @@
# Copyright 2013 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.
+set -e
platform="$1"
build_mode="$2"
diff --git a/.ci/scripts/build_examples_win32.sh b/.ci/scripts/build_examples_win32.sh
index bcf57a4b311f..8d87a2e660e6 100755
--- a/.ci/scripts/build_examples_win32.sh
+++ b/.ci/scripts/build_examples_win32.sh
@@ -2,6 +2,7 @@
# Copyright 2013 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.
+set -e
dart ./script/tool/bin/flutter_plugin_tools.dart build-examples --windows \
--packages-for-branch --log-timing
diff --git a/.ci/scripts/create_all_packages_app.sh b/.ci/scripts/create_all_packages_app.sh
index 8399e5e38a35..4440dfe2608a 100755
--- a/.ci/scripts/create_all_packages_app.sh
+++ b/.ci/scripts/create_all_packages_app.sh
@@ -2,6 +2,7 @@
# Copyright 2013 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.
+set -e
dart ./script/tool/bin/flutter_plugin_tools.dart create-all-packages-app \
--output-dir=. --exclude script/configs/exclude_all_packages_app.yaml
diff --git a/.ci/scripts/create_simulator.sh b/.ci/scripts/create_simulator.sh
index a12bbee0af0c..04d8fd1e9cd5 100755
--- a/.ci/scripts/create_simulator.sh
+++ b/.ci/scripts/create_simulator.sh
@@ -2,11 +2,14 @@
# Copyright 2013 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.
+set -e
+# Ensure that the create/boot pipeline fails if `create` fails
+set -o pipefail
# The name here must match remove_simulator.sh
readonly DEVICE_NAME=Flutter-iPhone
readonly DEVICE=com.apple.CoreSimulator.SimDeviceType.iPhone-14
-readonly OS=com.apple.CoreSimulator.SimRuntime.iOS-16-2
+readonly OS=com.apple.CoreSimulator.SimRuntime.iOS-16-4
xcrun simctl list
xcrun simctl create "$DEVICE_NAME" "$DEVICE" "$OS" | xargs xcrun simctl boot
diff --git a/.ci/scripts/custom_package_tests.sh b/.ci/scripts/custom_package_tests.sh
index 6b37bfbf1a96..c6473b267dc3 100755
--- a/.ci/scripts/custom_package_tests.sh
+++ b/.ci/scripts/custom_package_tests.sh
@@ -2,6 +2,7 @@
# Copyright 2013 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.
+set -e
# Exclusions
#
diff --git a/.ci/scripts/dart_unit_tests_win32.sh b/.ci/scripts/dart_unit_tests_win32.sh
index bd1ba77b5916..5fbe4764f6b3 100755
--- a/.ci/scripts/dart_unit_tests_win32.sh
+++ b/.ci/scripts/dart_unit_tests_win32.sh
@@ -2,6 +2,7 @@
# Copyright 2013 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.
+set -e
dart ./script/tool/bin/flutter_plugin_tools.dart test \
--exclude=script/configs/windows_unit_tests_exceptions.yaml \
diff --git a/.ci/scripts/drive_examples_win32.sh b/.ci/scripts/drive_examples_win32.sh
index c3e2e7bc5447..671330179e2f 100755
--- a/.ci/scripts/drive_examples_win32.sh
+++ b/.ci/scripts/drive_examples_win32.sh
@@ -2,6 +2,7 @@
# Copyright 2013 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.
+set -e
dart ./script/tool/bin/flutter_plugin_tools.dart drive-examples --windows \
--exclude=script/configs/exclude_integration_win32.yaml --packages-for-branch --log-timing
diff --git a/.ci/scripts/native_test_win32.sh b/.ci/scripts/native_test_win32.sh
index 37cf54e55c5c..0c86d3601e62 100755
--- a/.ci/scripts/native_test_win32.sh
+++ b/.ci/scripts/native_test_win32.sh
@@ -2,6 +2,7 @@
# Copyright 2013 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.
+set -e
dart ./script/tool/bin/flutter_plugin_tools.dart native-test --windows \
--no-integration --packages-for-branch --log-timing
diff --git a/.ci/scripts/plugin_tools_tests.sh b/.ci/scripts/plugin_tools_tests.sh
index 96eec4349f08..574a5fe51e46 100755
--- a/.ci/scripts/plugin_tools_tests.sh
+++ b/.ci/scripts/plugin_tools_tests.sh
@@ -2,6 +2,7 @@
# Copyright 2013 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.
+set -e
cd script/tool
dart pub run test
diff --git a/.ci/scripts/prepare_tool.sh b/.ci/scripts/prepare_tool.sh
index f93694bf1ff6..6c178170f501 100755
--- a/.ci/scripts/prepare_tool.sh
+++ b/.ci/scripts/prepare_tool.sh
@@ -2,6 +2,7 @@
# Copyright 2013 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.
+set -e
# To set FETCH_HEAD for "git merge-base" to work
git fetch origin main
diff --git a/.ci/scripts/remove_simulator.sh b/.ci/scripts/remove_simulator.sh
index e15354e600b7..09203011706f 100755
--- a/.ci/scripts/remove_simulator.sh
+++ b/.ci/scripts/remove_simulator.sh
@@ -2,10 +2,12 @@
# Copyright 2013 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.
+set -e
# The name here must match create_simulator.sh
readonly DEVICE_NAME=Flutter-iPhone
-xcrun simctl shutdown "$DEVICE_NAME"
+# Allow shutdown to fail; cases like "already shut down" exit with failure.
+xcrun simctl shutdown "$DEVICE_NAME" || :
xcrun simctl delete "$DEVICE_NAME"
xcrun simctl list
diff --git a/.ci/targets/plugin_tools_tests.yaml b/.ci/targets/plugin_tools_tests.yaml
deleted file mode 100644
index 265e74bdd06b..000000000000
--- a/.ci/targets/plugin_tools_tests.yaml
+++ /dev/null
@@ -1,5 +0,0 @@
-tasks:
- - name: prepare tool
- script: .ci/scripts/prepare_tool.sh
- - name: tool unit tests
- script: .ci/scripts/plugin_tools_tests.sh
diff --git a/.ci/targets/repo_tools_tests.yaml b/.ci/targets/repo_tools_tests.yaml
index a73053e34524..265e74bdd06b 100644
--- a/.ci/targets/repo_tools_tests.yaml
+++ b/.ci/targets/repo_tools_tests.yaml
@@ -1,4 +1,5 @@
tasks:
- name: prepare tool
script: .ci/scripts/prepare_tool.sh
- # TODO(stuartmorgan): Add actual tests here when moving the repo tooling.
+ - name: tool unit tests
+ script: .ci/scripts/plugin_tools_tests.sh
diff --git a/.cirrus.yml b/.cirrus.yml
index 7d00bcbc75cc..c8a7af48cce9 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -1,4 +1,4 @@
-gcp_credentials: ENCRYPTED[!3a93d98d7c95a41f5033834ef30e50928fc5d81239dc632b153c2628200a8187f3811cb01ce338b1ab3b6505a7a65c37!]
+gcp_credentials: ENCRYPTED[!9c8e92e8da192ce2a51b7d4ed9948c4250d0bae3660193d9b901196c9692abbebe784d4a32e9f38b328571d65f6e7aed!]
# Run on PRs and main branch post submit only. Don't run tests when tagging.
only_if: $CIRRUS_TAG == '' && ($CIRRUS_PR != '' || $CIRRUS_BRANCH == 'main')
@@ -27,7 +27,7 @@ macos_template: &MACOS_TEMPLATE
# PRs on macOS.
use_compute_credits: $CIRRUS_USER_COLLABORATOR == 'true'
macos_instance:
- image: ghcr.io/cirruslabs/macos-ventura-xcode:14
+ image: ghcr.io/cirruslabs/macos-ventura-xcode:14.3
flutter_upgrade_template: &FLUTTER_UPGRADE_TEMPLATE
upgrade_flutter_script:
@@ -83,11 +83,6 @@ task:
zone: us-central1-a
namespace: default
matrix:
- ### Platform-agnostic tasks ###
- - name: Linux plugin_tools_tests
- script:
- - cd script/tool
- - dart pub run test
# Repository rules and best-practice enforcement.
# Only channel-agnostic tests should go here since it is only run once
# (on Flutter master).
@@ -97,7 +92,7 @@ task:
license_script: $PLUGIN_TOOL_COMMAND license-check
# The major and minor version here should match the lowest version
# analyzed in legacy_version_analyze.
- pubspec_script: ./script/tool_runner.sh pubspec-check --min-min-flutter-version=3.0.0 --allow-dependencies=script/configs/allowed_unpinned_deps.yaml --allow-pinned-dependencies=script/configs/allowed_pinned_deps.yaml
+ pubspec_script: ./script/tool_runner.sh pubspec-check --min-min-flutter-version=3.3.0 --allow-dependencies=script/configs/allowed_unpinned_deps.yaml --allow-pinned-dependencies=script/configs/allowed_pinned_deps.yaml
readme_script:
- ./script/tool_runner.sh readme-check
# Re-run with --require-excerpts, skipping packages that still need
@@ -163,7 +158,7 @@ task:
matrix:
# Change the arguments to pubspec-check when changing these values.
env:
- CHANNEL: "3.0.5"
+ CHANNEL: "3.7.12"
DART_VERSION: "2.17.6"
env:
CHANNEL: "3.3.10"
@@ -265,18 +260,19 @@ task:
skip: $CIRRUS_PR != '' && $CHANNEL == 'stable'
env:
matrix:
- PACKAGE_SHARDING: "--shardIndex 0 --shardCount 7"
- PACKAGE_SHARDING: "--shardIndex 1 --shardCount 7"
- PACKAGE_SHARDING: "--shardIndex 2 --shardCount 7"
- PACKAGE_SHARDING: "--shardIndex 3 --shardCount 7"
- PACKAGE_SHARDING: "--shardIndex 4 --shardCount 7"
- PACKAGE_SHARDING: "--shardIndex 5 --shardCount 7"
- PACKAGE_SHARDING: "--shardIndex 6 --shardCount 7"
+ PACKAGE_SHARDING: "--shardIndex 0 --shardCount 8"
+ PACKAGE_SHARDING: "--shardIndex 1 --shardCount 8"
+ PACKAGE_SHARDING: "--shardIndex 2 --shardCount 8"
+ PACKAGE_SHARDING: "--shardIndex 3 --shardCount 8"
+ PACKAGE_SHARDING: "--shardIndex 4 --shardCount 8"
+ PACKAGE_SHARDING: "--shardIndex 5 --shardCount 8"
+ PACKAGE_SHARDING: "--shardIndex 6 --shardCount 8"
+ PACKAGE_SHARDING: "--shardIndex 7 --shardCount 8"
matrix:
CHANNEL: "master"
CHANNEL: "stable"
MAPS_API_KEY: ENCRYPTED[d6583b08f79f91ea4844c77460f04539965e46ad2fd97fb7c062b4dfe88016228b86ebe8c220ab4187e0c4bd773dc1e7]
- GCLOUD_FIREBASE_TESTLAB_KEY: ENCRYPTED[62dec6b6b5e7f32dd915552cc33202a350796824de621870bbc54c9ae28a10751e6bd8112f9e21f7f77e65fde1d588cf]
+ GCLOUD_FIREBASE_TESTLAB_KEY: ENCRYPTED[1a2eebf9367197bbe812d9a0ea83a53a05aeba4bb5e4964fe6a69727883cd87e51238d39237b1f80b0894c48419ac268]
build_script:
- ./script/tool_runner.sh build-examples --apk
lint_script:
@@ -306,6 +302,11 @@ task:
CHANNEL: "master"
CHANNEL: "stable"
<< : *BUILD_ALL_PACKAGES_APP_TEMPLATE
+ create_all_packages_app_legacy_script:
+ - $PLUGIN_TOOL_COMMAND create-all-packages-app --legacy-source=.ci/legacy_project/all_packages --output-dir=legacy/ --exclude script/configs/exclude_all_packages_app.yaml
+ build_all_packages_legacy_script:
+ - cd legacy/all_packages
+ - flutter build $BUILD_ALL_ARGS --debug
### Web tasks ###
- name: web-platform_tests
env:
@@ -350,7 +351,7 @@ task:
# currently have a hard-coded device.
create_simulator_script:
- xcrun simctl list
- - xcrun simctl create "iPhone 13" com.apple.CoreSimulator.SimDeviceType.iPhone-13 com.apple.CoreSimulator.SimRuntime.iOS-16-0
+ - xcrun simctl create "iPhone 13" com.apple.CoreSimulator.SimDeviceType.iPhone-13 com.apple.CoreSimulator.SimRuntime.iOS-16-4
local_tests_script:
# script/configs/linux_only_custom_test.yaml
# Custom tests need Chrome for these packages. (They run in linux-custom_package_tests)
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 8ac6d0e71b3f..9eb0b6fb7b03 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -20,9 +20,18 @@ jobs:
# Github Actions don't support templates so it is hard to share this snippet with another action
# If we eventually need to use this in more workflow, we could create a shell script that contains this
# snippet.
+ #
+ # This uses a pinned version of Flutter rather than `stable` so that it is
+ # not subject to out-of-band failures when new releases happen. It does
+ # not use the auto-rolled pin because there's no way for the autoroller
+ # to test the actual release flow, so changes would still show up in
+ # post-submit. A manually-rolled pin means that any changes here must be
+ # made deliberately, so that the person updating it knows to watch the
+ # next actual auto-release to ensure that it works, and knows to revert
+ # the change if it doesn't.
run: |
cd $HOME
- git clone https://github.com/flutter/flutter.git --depth 1 -b stable _flutter
+ git clone https://github.com/flutter/flutter.git --depth 1 -b 3.10.0 _flutter
echo "$HOME/_flutter/bin" >> $GITHUB_PATH
cd $GITHUB_WORKSPACE
# Checks out a copy of the repo.
diff --git a/.github/workflows/scorecards-analysis.yml b/.github/workflows/scorecards-analysis.yml
index ecccd64b43b5..d6b00ef80ff8 100644
--- a/.github/workflows/scorecards-analysis.yml
+++ b/.github/workflows/scorecards-analysis.yml
@@ -49,6 +49,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
- uses: github/codeql-action/upload-sarif@f3feb00acb00f31a6f60280e6ace9ca31d91c76a # v1.0.26
+ uses: github/codeql-action/upload-sarif@29b1f65c5e92e24fe6b6647da1eaabe529cec70f # v1.0.26
with:
sarif_file: results.sarif
diff --git a/analysis_options.yaml b/analysis_options.yaml
index 498d19dfb4ae..3c924bb88a30 100644
--- a/analysis_options.yaml
+++ b/analysis_options.yaml
@@ -13,8 +13,6 @@ analyzer:
# allow self-reference to deprecated members (we do this because otherwise we have
# to annotate every member in every test, assert, etc, when we deprecate something)
deprecated_member_use_from_same_package: ignore
- # Turned off until null-safe rollout is complete.
- unnecessary_null_comparison: ignore
exclude: # DIFFERENT FROM FLUTTER/FLUTTER
# Ignore generated files
- '**/*.g.dart'
diff --git a/packages/animations/CHANGELOG.md b/packages/animations/CHANGELOG.md
index a6733e2416c5..65cbb350dbf7 100644
--- a/packages/animations/CHANGELOG.md
+++ b/packages/animations/CHANGELOG.md
@@ -1,5 +1,6 @@
## NEXT
+* Updates minimum supported SDK version to Flutter 3.3/Dart 2.18.
* Aligns Dart and Flutter SDK constraints.
## 2.0.7
diff --git a/packages/animations/example/android/.pluginToolsConfig.yaml b/packages/animations/example/android/.pluginToolsConfig.yaml
new file mode 100644
index 000000000000..3b6017b7609a
--- /dev/null
+++ b/packages/animations/example/android/.pluginToolsConfig.yaml
@@ -0,0 +1,4 @@
+buildFlags:
+ _pluginToolsConfigGlobalKey:
+ - "--no-tree-shake-icons"
+ - "--dart-define=buildmode=testing"
diff --git a/packages/animations/example/android/build.gradle b/packages/animations/example/android/build.gradle
index 4b30292ebe1f..ce647a433bd0 100644
--- a/packages/animations/example/android/build.gradle
+++ b/packages/animations/example/android/build.gradle
@@ -1,5 +1,5 @@
buildscript {
- ext.kotlin_version = '1.6.21'
+ ext.kotlin_version = '1.7.10'
repositories {
google()
mavenCentral()
diff --git a/packages/animations/example/pubspec.yaml b/packages/animations/example/pubspec.yaml
index 5339c3ca0628..6a1c151615b8 100644
--- a/packages/animations/example/pubspec.yaml
+++ b/packages/animations/example/pubspec.yaml
@@ -6,8 +6,8 @@ publish_to: none
version: 0.0.1
environment:
- sdk: ">=2.17.0 <4.0.0"
- flutter: ">=3.0.0"
+ sdk: ">=2.18.0 <4.0.0"
+ flutter: ">=3.3.0"
dependencies:
animations:
diff --git a/packages/animations/pubspec.yaml b/packages/animations/pubspec.yaml
index 2633ec49488f..559bd2d46271 100644
--- a/packages/animations/pubspec.yaml
+++ b/packages/animations/pubspec.yaml
@@ -5,8 +5,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+
version: 2.0.7
environment:
- sdk: ">=2.17.0 <4.0.0"
- flutter: ">=3.0.0"
+ sdk: ">=2.18.0 <4.0.0"
+ flutter: ">=3.3.0"
dependencies:
flutter:
diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md
index 1a783b163915..856f2bac5b31 100644
--- a/packages/camera/camera/CHANGELOG.md
+++ b/packages/camera/camera/CHANGELOG.md
@@ -1,3 +1,11 @@
+## 0.10.5+1
+
+* Removes obsolete null checks on non-nullable values.
+
+## 0.10.5
+
+* Adds NV21 as an image streaming option for Android.
+
## 0.10.4
* Allows camera to be switched while video recording.
diff --git a/packages/camera/camera/example/.pluginToolsConfig.yaml b/packages/camera/camera/example/.pluginToolsConfig.yaml
new file mode 100644
index 000000000000..3b6017b7609a
--- /dev/null
+++ b/packages/camera/camera/example/.pluginToolsConfig.yaml
@@ -0,0 +1,4 @@
+buildFlags:
+ _pluginToolsConfigGlobalKey:
+ - "--no-tree-shake-icons"
+ - "--dart-define=buildmode=testing"
diff --git a/packages/camera/camera/example/lib/main.dart b/packages/camera/camera/example/lib/main.dart
index 73c9f052d48c..6dad1ebe7daa 100644
--- a/packages/camera/camera/example/lib/main.dart
+++ b/packages/camera/camera/example/lib/main.dart
@@ -250,9 +250,7 @@ class _CameraExampleHomeState extends State
child: Center(
child: AspectRatio(
aspectRatio:
- localVideoController.value.size != null
- ? localVideoController.value.aspectRatio
- : 1.0,
+ localVideoController.value.aspectRatio,
child: VideoPlayer(localVideoController)),
),
),
@@ -1000,7 +998,7 @@ class _CameraExampleHomeState extends State
: VideoPlayerController.file(File(videoFile!.path));
videoPlayerListener = () {
- if (videoController != null && videoController!.value.size != null) {
+ if (videoController != null) {
// Refreshing the state to update video player with the correct ratio.
if (mounted) {
setState(() {});
diff --git a/packages/camera/camera/lib/src/camera_image.dart b/packages/camera/camera/lib/src/camera_image.dart
index bfcad6626dd6..e1303f6d16e0 100644
--- a/packages/camera/camera/lib/src/camera_image.dart
+++ b/packages/camera/camera/lib/src/camera_image.dart
@@ -90,6 +90,9 @@ ImageFormatGroup _asImageFormatGroup(dynamic rawFormat) {
// android.graphics.ImageFormat.JPEG
case 256:
return ImageFormatGroup.jpeg;
+ // android.graphics.ImageFormat.NV21
+ case 17:
+ return ImageFormatGroup.nv21;
}
}
diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml
index 839f064bba12..5f18563836ff 100644
--- a/packages/camera/camera/pubspec.yaml
+++ b/packages/camera/camera/pubspec.yaml
@@ -4,7 +4,7 @@ description: A Flutter plugin for controlling the camera. Supports previewing
Dart.
repository: https://github.com/flutter/packages/tree/main/packages/camera/camera
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22
-version: 0.10.4
+version: 0.10.5+1
environment:
sdk: ">=2.18.0 <4.0.0"
@@ -21,9 +21,9 @@ flutter:
default_package: camera_web
dependencies:
- camera_android: ^0.10.5
+ camera_android: ^0.10.7
camera_avfoundation: ^0.9.13
- camera_platform_interface: ^2.4.0
+ camera_platform_interface: ^2.5.0
camera_web: ^0.3.1
flutter:
sdk: flutter
diff --git a/packages/camera/camera/test/camera_image_test.dart b/packages/camera/camera/test/camera_image_test.dart
index ecf4b509e2e4..5a046518a51a 100644
--- a/packages/camera/camera/test/camera_image_test.dart
+++ b/packages/camera/camera/test/camera_image_test.dart
@@ -139,6 +139,30 @@ void main() {
expect(cameraImage.format.group, ImageFormatGroup.yuv420);
});
+ test('$CameraImage has ImageFormatGroup.nv21 for android', () {
+ debugDefaultTargetPlatformOverride = TargetPlatform.android;
+
+ final CameraImage cameraImage =
+ CameraImage.fromPlatformData({
+ 'format': 17,
+ 'height': 1,
+ 'width': 4,
+ 'lensAperture': 1.8,
+ 'sensorExposureTime': 9991324,
+ 'sensorSensitivity': 92.0,
+ 'planes': [
+ {
+ 'bytes': Uint8List.fromList([1, 2, 3, 4]),
+ 'bytesPerPixel': 1,
+ 'bytesPerRow': 4,
+ 'height': 1,
+ 'width': 4
+ }
+ ]
+ });
+ expect(cameraImage.format.group, ImageFormatGroup.nv21);
+ });
+
test('$CameraImage has ImageFormatGroup.bgra8888 for iOS', () {
debugDefaultTargetPlatformOverride = TargetPlatform.iOS;
@@ -162,6 +186,7 @@ void main() {
});
expect(cameraImage.format.group, ImageFormatGroup.bgra8888);
});
+
test('$CameraImage has ImageFormatGroup.unknown', () {
final CameraImage cameraImage =
CameraImage.fromPlatformData({
diff --git a/packages/camera/camera_android/CHANGELOG.md b/packages/camera/camera_android/CHANGELOG.md
index 4adba0df5152..28552d33c3ab 100644
--- a/packages/camera/camera_android/CHANGELOG.md
+++ b/packages/camera/camera_android/CHANGELOG.md
@@ -1,3 +1,12 @@
+## 0.10.8+2
+
+* Removes obsolete null checks on non-nullable values.
+
+## 0.10.8+1
+
+* Fixes lint errors.
+* Updates minimum supported SDK version to Flutter 3.3/Dart 2.18.
+
## 0.10.8
* Updates gradle, AGP and fixes some lint errors.
diff --git a/packages/camera/camera_android/android/build.gradle b/packages/camera/camera_android/android/build.gradle
index 836aeaf13670..ef8d9e297674 100644
--- a/packages/camera/camera_android/android/build.gradle
+++ b/packages/camera/camera_android/android/build.gradle
@@ -34,7 +34,6 @@ android {
compileSdkVersion 33
defaultConfig {
- targetSdkVersion 31
minSdkVersion 21
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
@@ -48,10 +47,6 @@ android {
targetCompatibility JavaVersion.VERSION_1_8
}
- lint {
- baseline = file("lint-baseline.xml")
- }
-
testOptions {
unitTests.includeAndroidResources = true
unitTests.returnDefaultValues = true
diff --git a/packages/camera/camera_android/android/lint-baseline.xml b/packages/camera/camera_android/android/lint-baseline.xml
deleted file mode 100644
index 7bf52079ebc2..000000000000
--- a/packages/camera/camera_android/android/lint-baseline.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/CameraDeviceWrapper.java b/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/CameraDeviceWrapper.java
index 6a8a8f6bee0b..d86535c1b0a8 100644
--- a/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/CameraDeviceWrapper.java
+++ b/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/CameraDeviceWrapper.java
@@ -24,7 +24,6 @@ interface CameraDeviceWrapper {
@TargetApi(Build.VERSION_CODES.P)
void createCaptureSession(SessionConfiguration config) throws CameraAccessException;
- @TargetApi(Build.VERSION_CODES.LOLLIPOP)
void createCaptureSession(
@NonNull List outputs,
@NonNull CameraCaptureSession.StateCallback callback,
diff --git a/packages/camera/camera_android/example/.pluginToolsConfig.yaml b/packages/camera/camera_android/example/.pluginToolsConfig.yaml
new file mode 100644
index 000000000000..3b6017b7609a
--- /dev/null
+++ b/packages/camera/camera_android/example/.pluginToolsConfig.yaml
@@ -0,0 +1,4 @@
+buildFlags:
+ _pluginToolsConfigGlobalKey:
+ - "--no-tree-shake-icons"
+ - "--dart-define=buildmode=testing"
diff --git a/packages/camera/camera_android/example/lib/main.dart b/packages/camera/camera_android/example/lib/main.dart
index dd02be3d7ae6..5162d3a22cfb 100644
--- a/packages/camera/camera_android/example/lib/main.dart
+++ b/packages/camera/camera_android/example/lib/main.dart
@@ -253,9 +253,7 @@ class _CameraExampleHomeState extends State
child: Center(
child: AspectRatio(
aspectRatio:
- localVideoController.value.size != null
- ? localVideoController.value.aspectRatio
- : 1.0,
+ localVideoController.value.aspectRatio,
child: VideoPlayer(localVideoController)),
),
),
@@ -1008,7 +1006,7 @@ class _CameraExampleHomeState extends State
: VideoPlayerController.file(File(videoFile!.path));
videoPlayerListener = () {
- if (videoController != null && videoController!.value.size != null) {
+ if (videoController != null) {
// Refreshing the state to update video player with the correct ratio.
if (mounted) {
setState(() {});
diff --git a/packages/camera/camera_android/example/pubspec.yaml b/packages/camera/camera_android/example/pubspec.yaml
index 39f40663d100..bee460e92fa5 100644
--- a/packages/camera/camera_android/example/pubspec.yaml
+++ b/packages/camera/camera_android/example/pubspec.yaml
@@ -3,8 +3,8 @@ description: Demonstrates how to use the camera plugin.
publish_to: none
environment:
- sdk: ">=2.17.0 <4.0.0"
- flutter: ">=3.0.0"
+ sdk: ">=2.18.0 <4.0.0"
+ flutter: ">=3.3.0"
dependencies:
camera_android:
@@ -32,8 +32,3 @@ dev_dependencies:
flutter:
uses-material-design: true
-
-# FOR TESTING ONLY. DO NOT MERGE.
-dependency_overrides:
- camera_android:
- path: ../../../camera/camera_android
diff --git a/packages/camera/camera_android/pubspec.yaml b/packages/camera/camera_android/pubspec.yaml
index deef7ee6a7ce..9da632825dd4 100644
--- a/packages/camera/camera_android/pubspec.yaml
+++ b/packages/camera/camera_android/pubspec.yaml
@@ -3,11 +3,11 @@ description: Android implementation of the camera plugin.
repository: https://github.com/flutter/packages/tree/main/packages/camera/camera_android
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22
-version: 0.10.8
+version: 0.10.8+2
environment:
- sdk: ">=2.17.0 <4.0.0"
- flutter: ">=3.0.0"
+ sdk: ">=2.18.0 <4.0.0"
+ flutter: ">=3.3.0"
flutter:
plugin:
diff --git a/packages/camera/camera_android_camerax/CHANGELOG.md b/packages/camera/camera_android_camerax/CHANGELOG.md
index 12dd55552974..16da75f45970 100644
--- a/packages/camera/camera_android_camerax/CHANGELOG.md
+++ b/packages/camera/camera_android_camerax/CHANGELOG.md
@@ -1,22 +1,26 @@
-## NEXT
-
-* Updates minimum Flutter version to 3.3.
-* Creates camera_android_camerax plugin for development.
-* Adds CameraInfo class and removes unnecessary code from plugin.
-* Adds CameraSelector class.
-* Adds ProcessCameraProvider class.
-* Bump CameraX version to 1.3.0-alpha02.
-* Adds Camera and UseCase classes, along with methods for binding UseCases to a lifecycle with the ProcessCameraProvider.
-* Bump CameraX version to 1.3.0-alpha03 and Kotlin version to 1.8.0.
-* Changes instance manager to allow the separate creation of identical objects.
-* Adds Preview and Surface classes, along with other methods needed to implement camera preview.
-* Adds implementation of availableCameras().
-* Implements camera preview, createCamera, initializeCamera, onCameraError, onDeviceOrientationChanged, and onCameraInitialized.
-* Adds integration test to plugin.
-* Bump CameraX version to 1.3.0-alpha04.
-* Fixes instance manager hot restart behavior and fixes Java casting issue.
-* Implements image capture.
-* Fixes cast of CameraInfo to fix integration test failure.
-* Updates internal Java InstanceManager to only stop finalization callbacks when stopped.
-* Implements image streaming.
-* Provides LifecycleOwner implementation for Activities that use the plugin that do not implement it themselves.
+## 0.5.0+4
+
+* Removes obsolete null checks on non-nullable values.
+
+## 0.5.0+3
+
+* Fixes Java lints.
+
+## 0.5.0+2
+
+* Adds a dependency on kotlin-bom to align versions of Kotlin transitive dependencies.
+* Removes note in `README.md` regarding duplicate Kotlin classes issue.
+
+## 0.5.0+1
+
+* Update `README.md` to include known duplicate Kotlin classes issue.
+
+## 0.5.0
+
+* Initial release of this `camera` implementation that supports:
+ * Image capture
+ * Video recording
+ * Displaying a live camera preview
+ * Image streaming
+
+ See [`README.md`](README.md) for more details on the limitations of this implementation.
diff --git a/packages/camera/camera_android_camerax/CONTRIBUTING.md b/packages/camera/camera_android_camerax/CONTRIBUTING.md
new file mode 100644
index 000000000000..3d365d791e57
--- /dev/null
+++ b/packages/camera/camera_android_camerax/CONTRIBUTING.md
@@ -0,0 +1,75 @@
+# Contributing to camera\_android\_camerax
+
+## Plugin structure
+
+The `camera_platform_interface` implementation is located at
+`lib/src/android_camera_camerax.dart`, and it is implemented using Dart classes
+that are wrapped versions of native Android Java classes.
+
+In this approach, each native Android library used in the plugin implementation
+is represented by an equivalent Dart class. Instances of these classes are
+considered paired and represent each other in Java and Dart, respectively. An
+`InstanceManager`, which is essentially a map between `long` identifiers and
+objects that also provides notifications when an object has become unreachable
+by memory. There is both a Dart and Java `InstanceManager` implementation, so
+when a Dart instance is created that represens an Android native instance,
+both are stored in the `InstanceManager` of their respective language with a
+shared `long` identifier. These `InstanceManager`s take callbacks that run
+when objects become unrechable or removed, allowing the Dart library to easily
+handle removing references to native resources automatically. To ensure all
+created instances are properly managed and to more easily allow for testing,
+each wrapped Android native class in Dart takes an `InstanceManager` and has
+a detached constructor, a constructor that allows for the creation of instances
+not attached to the `InstanceManager` and unlinked to a paired Android native
+instance.
+
+In `lib/src/`, you will find all of the Dart-wrapped native Android classes that
+the plugin currently uses in its implementation. As aforementioned, each of
+these classes uses an `InstanceManager` (implementation in `instance_manager.dart`)
+to manage objects that are created by the plugin implementation that map to objects
+of the same type created in the native Android code. This plugin uses [`pigeon`][1]
+to generate the communication layer between Flutter and native Android code, so each
+of these Dart-wrapped classes may also have Host API and Flutter API implementations
+that handle communication to the host native Android platform and from the host
+native Android platform, respectively. The communication interface is defined in
+the `pigeons/camerax_library.dart` file. After editing the communication interface,
+regenerate the communication layer by running
+`dart run pigeon --input pigeons/camerax_library.dart` from the plugin root.
+
+In the native Java Android code in `android/src/main/java/io/flutter/plugins/camerax/`,
+you'll find the Host API and Flutter API implementations of the same classes
+wrapped with Dart in `lib/src/` that handle communication from that Dart code
+and to that Dart code, respectively. The Host API implementations should directly
+delegate calls to the CameraX or other wrapped Android libraries and should not
+have any additional logic or abstraction; any exceptions should be thoroughly
+documented in the code. As aforementioned, the objects created in the native
+Android code map to objects created on the Dart side and are also managed by
+an `InstanceManager` (implementation in `InstanceManager.java`).
+
+If CameraX or other Android classes that you need to access do not have a
+duplicately named implementation in `lib/src/`, then follow the same structure
+described above to add them.
+
+For more information, please see the [design document][2] or feel free
+to ask any questions on the #hackers-ecosystem channel on [Discord][6]. For
+more information on contributing packages in general, check out our
+[contribution guide][3].
+
+## Testing
+
+While none of the generated `pigeon` files are tested, all plugin impelementation and
+wrapped native Android classes (Java & Dart) are tested. You can find the Java tests under
+`android/src/test/java/io/flutter/plugins/camerax/` and the Dart tests under `test/`. To
+run these tests, please see the instructions in the [running plugin tests guide][5].
+
+Besides [`pigeon`][1], this plugin also uses [`mockito`][4] to generate mock objects for
+testing purposes. To generate the mock objects, run
+`dart run build_runner build --delete-conflicting-outputs`.
+
+
+[1]: https://pub.dev/packages/pigeon
+[2]: https://docs.google.com/document/d/1wXB1zNzYhd2SxCu1_BK3qmNWRhonTB6qdv4erdtBQqo/edit?usp=sharing&resourcekey=0-WOBqqOKiO9SARnziBg28pg
+[3]: https://github.com/flutter/packages/blob/main/CONTRIBUTING.md
+[4]: https://pub.dev/packages/mockito
+[5]: https://github.com/flutter/flutter/wiki/Plugin-Tests#running-tests
+[6]: https://github.com/flutter/flutter/wiki/Chat
\ No newline at end of file
diff --git a/packages/camera/camera_android_camerax/README.md b/packages/camera/camera_android_camerax/README.md
index 06d837ac7214..a357008b8ba4 100644
--- a/packages/camera/camera_android_camerax/README.md
+++ b/packages/camera/camera_android_camerax/README.md
@@ -1,3 +1,68 @@
-# camera_android_camerax
+# camera\_android\_camerax
-An implementation of the camera plugin on Android using CameraX.
+An Android implementation of [`camera`][1] that uses the [CameraX library][2].
+
+*Note*: This package is under development, so please note the
+[missing features and limitations](#missing-features-and-limitations), but
+otherwise feel free to try out the current implementation and provide any
+feedback by filing issues under [`flutter/flutter`][5] with `[camerax]` in
+the title, which will be actively triaged.
+
+## Usage
+
+This package is [non-endorsed][3]; the endorsed Android implementation of `camera`
+is [`camera_android`][4]. To use this implementation of the plugin instead of
+`camera_android`, you will need to specify it in your `pubsepc.yaml` file as a
+dependency in addition to `camera`:
+
+```yaml
+dependencies:
+ # ...along with your other dependencies
+ camera: ^0.10.4
+ camera_android_camerax: ^0.5.0
+```
+
+## Missing features and limitations
+
+### Resolution configuration \[[Issue #120462][120462]\]
+
+Any specified `ResolutionPreset` wll go unused in favor of CameraX defaults and
+`onCameraResolutionChanged` is unimplemented.
+
+### Locking/Unlocking capture orientation \[[Issue #125915][125915]\]
+
+`lockCaptureOrientation` & `unLockCaptureOrientation` are unimplemented.
+
+### Flash mode configuration \[[Issue #120715][120715]\]
+
+`setFlashMode` is unimplemented.
+
+### Exposure mode, point, & offset configuration \[[Issue #120468][120468]\]
+
+`setExposureMode`, `setExposurePoint`, & `setExposureOffset` are unimplemented.
+
+### Focus mode & point configuration \[[Issue #120467][120467]\]
+
+`setFocusMode` & `setFocusPoint` are unimplemented.
+
+### Zoom configuration \[[Issue #125371][125371]\]
+
+`setZoomLevel` is unimplemented.
+
+## Contributing
+
+For more information on contributing to this plugin, see [`CONTRIBUTING.md`](CONTRIBUTING.md).
+
+
+
+[1]: https://pub.dev/packages/camera
+[2]: https://developer.android.com/training/camerax
+[3]: https://docs.flutter.dev/packages-and-plugins/developing-packages#non-endorsed-federated-plugin
+[4]: https://pub.dev/packages/camera_android
+[5]: https://github.com/flutter/flutter/issues/new/choose
+[120462]: https://github.com/flutter/flutter/issues/120462
+[125915]: https://github.com/flutter/flutter/issues/125915
+[120715]: https://github.com/flutter/flutter/issues/120715
+[120468]: https://github.com/flutter/flutter/issues/120468
+[120467]: https://github.com/flutter/flutter/issues/120467
+[125371]: https://github.com/flutter/flutter/issues/125371
\ No newline at end of file
diff --git a/packages/camera/camera_android_camerax/android/build.gradle b/packages/camera/camera_android_camerax/android/build.gradle
index d056449de871..77b10450914a 100644
--- a/packages/camera/camera_android_camerax/android/build.gradle
+++ b/packages/camera/camera_android_camerax/android/build.gradle
@@ -56,19 +56,23 @@ android {
checkAllWarnings true
warningsAsErrors true
disable 'AndroidGradlePluginVersion', 'GradleDependency', 'InvalidPackage'
- baseline file("lint-baseline.xml")
}
}
dependencies {
// CameraX core library using the camera2 implementation must use same version number.
- def camerax_version = "1.3.0-alpha04"
+ def camerax_version = "1.3.0-alpha05"
implementation "androidx.camera:camera-core:${camerax_version}"
implementation "androidx.camera:camera-camera2:${camerax_version}"
implementation "androidx.camera:camera-lifecycle:${camerax_version}"
+ implementation "androidx.camera:camera-video:${camerax_version}"
implementation 'com.google.guava:guava:31.1-android'
testImplementation 'junit:junit:4.13.2'
testImplementation 'org.mockito:mockito-inline:5.0.0'
testImplementation 'androidx.test:core:1.4.0'
testImplementation 'org.robolectric:robolectric:4.8'
+
+ // org.jetbrains.kotlin:kotlin-bom artifact purpose is to align kotlin stdlib and related code versions.
+ // See: https://youtrack.jetbrains.com/issue/KT-55297/kotlin-stdlib-should-declare-constraints-on-kotlin-stdlib-jdk8-and-kotlin-stdlib-jdk7
+ implementation(platform("org.jetbrains.kotlin:kotlin-bom:1.8.10"))
}
diff --git a/packages/camera/camera_android_camerax/android/lint-baseline.xml b/packages/camera/camera_android_camerax/android/lint-baseline.xml
deleted file mode 100644
index 1142794741a6..000000000000
--- a/packages/camera/camera_android_camerax/android/lint-baseline.xml
+++ /dev/null
@@ -1,1434 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraAndroidCameraxPlugin.java b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraAndroidCameraxPlugin.java
index 31f996d26e24..dd8ab514652c 100644
--- a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraAndroidCameraxPlugin.java
+++ b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraAndroidCameraxPlugin.java
@@ -7,6 +7,7 @@
import android.app.Activity;
import android.content.Context;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.lifecycle.LifecycleOwner;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
@@ -19,11 +20,17 @@
public final class CameraAndroidCameraxPlugin implements FlutterPlugin, ActivityAware {
private InstanceManager instanceManager;
private FlutterPluginBinding pluginBinding;
+ private PendingRecordingHostApiImpl pendingRecordingHostApiImpl;
+ private RecorderHostApiImpl recorderHostApiImpl;
+ private VideoCaptureHostApiImpl videoCaptureHostApiImpl;
private ImageAnalysisHostApiImpl imageAnalysisHostApiImpl;
private ImageCaptureHostApiImpl imageCaptureHostApiImpl;
- public SystemServicesHostApiImpl systemServicesHostApiImpl;
+ public @Nullable SystemServicesHostApiImpl systemServicesHostApiImpl;
- @VisibleForTesting ProcessCameraProviderHostApiImpl processCameraProviderHostApiImpl;
+ @VisibleForTesting
+ public @Nullable ProcessCameraProviderHostApiImpl processCameraProviderHostApiImpl;
+
+ @VisibleForTesting public @Nullable LiveDataHostApiImpl liveDataHostApiImpl;
/**
* Initialize this within the {@code #configureFlutterEngine} of a Flutter activity or fragment.
@@ -48,8 +55,10 @@ public void setUp(
// Set up Host APIs.
GeneratedCameraXLibrary.InstanceManagerHostApi.setup(
binaryMessenger, () -> instanceManager.clear());
+ GeneratedCameraXLibrary.CameraHostApi.setup(
+ binaryMessenger, new CameraHostApiImpl(binaryMessenger, instanceManager));
GeneratedCameraXLibrary.CameraInfoHostApi.setup(
- binaryMessenger, new CameraInfoHostApiImpl(instanceManager));
+ binaryMessenger, new CameraInfoHostApiImpl(binaryMessenger, instanceManager));
GeneratedCameraXLibrary.CameraSelectorHostApi.setup(
binaryMessenger, new CameraSelectorHostApiImpl(binaryMessenger, instanceManager));
GeneratedCameraXLibrary.JavaObjectHostApi.setup(
@@ -58,19 +67,36 @@ public void setUp(
new ProcessCameraProviderHostApiImpl(binaryMessenger, instanceManager, context);
GeneratedCameraXLibrary.ProcessCameraProviderHostApi.setup(
binaryMessenger, processCameraProviderHostApiImpl);
- systemServicesHostApiImpl = new SystemServicesHostApiImpl(binaryMessenger, instanceManager);
+ systemServicesHostApiImpl =
+ new SystemServicesHostApiImpl(binaryMessenger, instanceManager, context);
GeneratedCameraXLibrary.SystemServicesHostApi.setup(binaryMessenger, systemServicesHostApiImpl);
GeneratedCameraXLibrary.PreviewHostApi.setup(
binaryMessenger, new PreviewHostApiImpl(binaryMessenger, instanceManager, textureRegistry));
imageCaptureHostApiImpl =
new ImageCaptureHostApiImpl(binaryMessenger, instanceManager, context);
GeneratedCameraXLibrary.ImageCaptureHostApi.setup(binaryMessenger, imageCaptureHostApiImpl);
+ GeneratedCameraXLibrary.CameraHostApi.setup(
+ binaryMessenger, new CameraHostApiImpl(binaryMessenger, instanceManager));
+ liveDataHostApiImpl = new LiveDataHostApiImpl(binaryMessenger, instanceManager);
+ GeneratedCameraXLibrary.LiveDataHostApi.setup(binaryMessenger, liveDataHostApiImpl);
+ GeneratedCameraXLibrary.ObserverHostApi.setup(
+ binaryMessenger, new ObserverHostApiImpl(binaryMessenger, instanceManager));
imageAnalysisHostApiImpl = new ImageAnalysisHostApiImpl(binaryMessenger, instanceManager);
GeneratedCameraXLibrary.ImageAnalysisHostApi.setup(binaryMessenger, imageAnalysisHostApiImpl);
GeneratedCameraXLibrary.AnalyzerHostApi.setup(
binaryMessenger, new AnalyzerHostApiImpl(binaryMessenger, instanceManager));
GeneratedCameraXLibrary.ImageProxyHostApi.setup(
binaryMessenger, new ImageProxyHostApiImpl(binaryMessenger, instanceManager));
+ GeneratedCameraXLibrary.RecordingHostApi.setup(
+ binaryMessenger, new RecordingHostApiImpl(binaryMessenger, instanceManager));
+ recorderHostApiImpl = new RecorderHostApiImpl(binaryMessenger, instanceManager, context);
+ GeneratedCameraXLibrary.RecorderHostApi.setup(binaryMessenger, recorderHostApiImpl);
+ pendingRecordingHostApiImpl =
+ new PendingRecordingHostApiImpl(binaryMessenger, instanceManager, context);
+ GeneratedCameraXLibrary.PendingRecordingHostApi.setup(
+ binaryMessenger, pendingRecordingHostApiImpl);
+ videoCaptureHostApiImpl = new VideoCaptureHostApiImpl(binaryMessenger, instanceManager);
+ GeneratedCameraXLibrary.VideoCaptureHostApi.setup(binaryMessenger, videoCaptureHostApiImpl);
}
@Override
@@ -89,19 +115,18 @@ public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
@Override
public void onAttachedToActivity(@NonNull ActivityPluginBinding activityPluginBinding) {
- setUp(
- pluginBinding.getBinaryMessenger(),
- pluginBinding.getApplicationContext(),
- pluginBinding.getTextureRegistry());
- updateContext(pluginBinding.getApplicationContext());
-
Activity activity = activityPluginBinding.getActivity();
+ setUp(pluginBinding.getBinaryMessenger(), activity, pluginBinding.getTextureRegistry());
+ updateContext(activity);
+
if (activity instanceof LifecycleOwner) {
processCameraProviderHostApiImpl.setLifecycleOwner((LifecycleOwner) activity);
+ liveDataHostApiImpl.setLifecycleOwner((LifecycleOwner) activity);
} else {
ProxyLifecycleProvider proxyLifecycleProvider = new ProxyLifecycleProvider(activity);
processCameraProviderHostApiImpl.setLifecycleOwner(proxyLifecycleProvider);
+ liveDataHostApiImpl.setLifecycleOwner(proxyLifecycleProvider);
}
systemServicesHostApiImpl.setActivity(activity);
@@ -133,6 +158,15 @@ public void updateContext(@NonNull Context context) {
if (processCameraProviderHostApiImpl != null) {
processCameraProviderHostApiImpl.setContext(context);
}
+ if (recorderHostApiImpl != null) {
+ recorderHostApiImpl.setContext(context);
+ }
+ if (pendingRecordingHostApiImpl != null) {
+ pendingRecordingHostApiImpl.setContext(context);
+ }
+ if (systemServicesHostApiImpl != null) {
+ systemServicesHostApiImpl.setContext(context);
+ }
if (imageCaptureHostApiImpl != null) {
imageCaptureHostApiImpl.setContext(context);
}
diff --git a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraFlutterApiImpl.java b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraFlutterApiImpl.java
index a03548399485..cfc40be1819a 100644
--- a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraFlutterApiImpl.java
+++ b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraFlutterApiImpl.java
@@ -4,14 +4,16 @@
package io.flutter.plugins.camerax;
+import androidx.annotation.NonNull;
import androidx.camera.core.Camera;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugins.camerax.GeneratedCameraXLibrary.CameraFlutterApi;
public class CameraFlutterApiImpl extends CameraFlutterApi {
- private final InstanceManager instanceManager;
+ private final @NonNull InstanceManager instanceManager;
- public CameraFlutterApiImpl(BinaryMessenger binaryMessenger, InstanceManager instanceManager) {
+ public CameraFlutterApiImpl(
+ @NonNull BinaryMessenger binaryMessenger, @NonNull InstanceManager instanceManager) {
super(binaryMessenger);
this.instanceManager = instanceManager;
}
diff --git a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraHostApiImpl.java b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraHostApiImpl.java
new file mode 100644
index 000000000000..98f5f74b959d
--- /dev/null
+++ b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraHostApiImpl.java
@@ -0,0 +1,41 @@
+// Copyright 2013 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.
+
+package io.flutter.plugins.camerax;
+
+import androidx.annotation.NonNull;
+import androidx.camera.core.Camera;
+import androidx.camera.core.CameraInfo;
+import io.flutter.plugin.common.BinaryMessenger;
+import io.flutter.plugins.camerax.GeneratedCameraXLibrary.CameraHostApi;
+import java.util.Objects;
+
+public class CameraHostApiImpl implements CameraHostApi {
+ private final BinaryMessenger binaryMessenger;
+ private final InstanceManager instanceManager;
+
+ public CameraHostApiImpl(
+ @NonNull BinaryMessenger binaryMessenger, @NonNull InstanceManager instanceManager) {
+ this.binaryMessenger = binaryMessenger;
+ this.instanceManager = instanceManager;
+ }
+
+ /**
+ * Retrieves the {@link CameraInfo} instance that contains information about the {@link Camera}
+ * instance with the specified identifier.
+ */
+ @Override
+ @NonNull
+ public Long getCameraInfo(@NonNull Long identifier) {
+ Camera camera = (Camera) Objects.requireNonNull(instanceManager.getInstance(identifier));
+ CameraInfo cameraInfo = camera.getCameraInfo();
+
+ if (!instanceManager.containsInstance(cameraInfo)) {
+ CameraInfoFlutterApiImpl cameraInfoFlutterApiImpl =
+ new CameraInfoFlutterApiImpl(binaryMessenger, instanceManager);
+ cameraInfoFlutterApiImpl.create(cameraInfo, reply -> {});
+ }
+ return instanceManager.getIdentifierForStrongReference(cameraInfo);
+ }
+}
diff --git a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraInfoFlutterApiImpl.java b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraInfoFlutterApiImpl.java
index c538e420cc7e..8b0e1ff6b3e2 100644
--- a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraInfoFlutterApiImpl.java
+++ b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraInfoFlutterApiImpl.java
@@ -4,20 +4,26 @@
package io.flutter.plugins.camerax;
+import androidx.annotation.NonNull;
import androidx.camera.core.CameraInfo;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugins.camerax.GeneratedCameraXLibrary.CameraInfoFlutterApi;
public class CameraInfoFlutterApiImpl extends CameraInfoFlutterApi {
- private final InstanceManager instanceManager;
+ private final @NonNull InstanceManager instanceManager;
public CameraInfoFlutterApiImpl(
- BinaryMessenger binaryMessenger, InstanceManager instanceManager) {
+ @NonNull BinaryMessenger binaryMessenger, @NonNull InstanceManager instanceManager) {
super(binaryMessenger);
this.instanceManager = instanceManager;
}
+ /**
+ * Creates a {@link CameraInfo} instance in Dart. {@code reply} is not used so it can be empty.
+ */
void create(CameraInfo cameraInfo, Reply reply) {
- create(instanceManager.addHostCreatedInstance(cameraInfo), reply);
+ if (!instanceManager.containsInstance(cameraInfo)) {
+ create(instanceManager.addHostCreatedInstance(cameraInfo), reply);
+ }
}
}
diff --git a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraInfoHostApiImpl.java b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraInfoHostApiImpl.java
index d960b7fff70a..83eb359cdb5e 100644
--- a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraInfoHostApiImpl.java
+++ b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraInfoHostApiImpl.java
@@ -5,21 +5,91 @@
package io.flutter.plugins.camerax;
import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
import androidx.camera.core.CameraInfo;
+import androidx.camera.core.CameraState;
+import androidx.camera.core.ExposureState;
+import androidx.camera.core.ZoomState;
+import androidx.lifecycle.LiveData;
+import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugins.camerax.GeneratedCameraXLibrary.CameraInfoHostApi;
+import io.flutter.plugins.camerax.GeneratedCameraXLibrary.LiveDataSupportedType;
import java.util.Objects;
public class CameraInfoHostApiImpl implements CameraInfoHostApi {
+ private final BinaryMessenger binaryMessenger;
private final InstanceManager instanceManager;
- public CameraInfoHostApiImpl(InstanceManager instanceManager) {
+ @VisibleForTesting public @NonNull LiveDataFlutterApiWrapper liveDataFlutterApiWrapper;
+
+ public CameraInfoHostApiImpl(
+ @NonNull BinaryMessenger binaryMessenger, @NonNull InstanceManager instanceManager) {
+ this.binaryMessenger = binaryMessenger;
this.instanceManager = instanceManager;
+ this.liveDataFlutterApiWrapper =
+ new LiveDataFlutterApiWrapper(binaryMessenger, instanceManager);
}
+ /**
+ * Retrieves the sensor rotation degrees of the {@link androidx.camera.core.Camera} that is
+ * represented by the {@link CameraInfo} with the specified identifier.
+ */
@Override
+ @NonNull
public Long getSensorRotationDegrees(@NonNull Long identifier) {
CameraInfo cameraInfo =
(CameraInfo) Objects.requireNonNull(instanceManager.getInstance(identifier));
return Long.valueOf(cameraInfo.getSensorRotationDegrees());
}
+
+ /**
+ * Retrieves the {@link LiveData} of the {@link CameraState} that is tied to the {@link
+ * androidx.camera.core.Camera} that is represented by the {@link CameraInfo} with the specified
+ * identifier.
+ */
+ @Override
+ @NonNull
+ public Long getCameraState(@NonNull Long identifier) {
+ CameraInfo cameraInfo =
+ (CameraInfo) Objects.requireNonNull(instanceManager.getInstance(identifier));
+ LiveData liveCameraState = cameraInfo.getCameraState();
+ liveDataFlutterApiWrapper.create(
+ liveCameraState, LiveDataSupportedType.CAMERA_STATE, reply -> {});
+ return instanceManager.getIdentifierForStrongReference(liveCameraState);
+ }
+
+ /**
+ * Retrieves the {@link ExposureState} of the {@link CameraInfo} with the specified identifier.
+ */
+ @Override
+ @NonNull
+ public Long getExposureState(@NonNull Long identifier) {
+ CameraInfo cameraInfo =
+ (CameraInfo) Objects.requireNonNull(instanceManager.getInstance(identifier));
+ ExposureState exposureState = cameraInfo.getExposureState();
+
+ ExposureStateFlutterApiImpl exposureStateFlutterApiImpl =
+ new ExposureStateFlutterApiImpl(binaryMessenger, instanceManager);
+ exposureStateFlutterApiImpl.create(exposureState, result -> {});
+
+ return instanceManager.getIdentifierForStrongReference(exposureState);
+ }
+
+ /**
+ * Retrieves the {@link LiveData} of the {@link ZoomState} of the {@link CameraInfo} with the
+ * specified identifier.
+ */
+ @NonNull
+ @Override
+ public Long getZoomState(@NonNull Long identifier) {
+ CameraInfo cameraInfo =
+ (CameraInfo) Objects.requireNonNull(instanceManager.getInstance(identifier));
+ LiveData zoomState = cameraInfo.getZoomState();
+
+ LiveDataFlutterApiWrapper liveDataFlutterApiWrapper =
+ new LiveDataFlutterApiWrapper(binaryMessenger, instanceManager);
+ liveDataFlutterApiWrapper.create(zoomState, LiveDataSupportedType.ZOOM_STATE, reply -> {});
+
+ return instanceManager.getIdentifierForStrongReference(zoomState);
+ }
}
diff --git a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraPermissionsManager.java b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraPermissionsManager.java
index 19b1ee569a9b..28093ec43711 100644
--- a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraPermissionsManager.java
+++ b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraPermissionsManager.java
@@ -8,6 +8,7 @@
import android.Manifest.permission;
import android.app.Activity;
import android.content.pm.PackageManager;
+import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
@@ -99,7 +100,8 @@ static final class CameraRequestPermissionsListener
}
@Override
- public boolean onRequestPermissionsResult(int id, String[] permissions, int[] grantResults) {
+ public boolean onRequestPermissionsResult(
+ int id, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (alreadyCalled || id != CAMERA_REQUEST_ID) {
return false;
}
diff --git a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraSelectorFlutterApiImpl.java b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraSelectorFlutterApiImpl.java
index 6ca3782d8b59..a0b30fa25417 100644
--- a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraSelectorFlutterApiImpl.java
+++ b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraSelectorFlutterApiImpl.java
@@ -4,6 +4,7 @@
package io.flutter.plugins.camerax;
+import androidx.annotation.NonNull;
import androidx.camera.core.CameraSelector;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugins.camerax.GeneratedCameraXLibrary.CameraSelectorFlutterApi;
@@ -12,7 +13,7 @@ public class CameraSelectorFlutterApiImpl extends CameraSelectorFlutterApi {
private final InstanceManager instanceManager;
public CameraSelectorFlutterApiImpl(
- BinaryMessenger binaryMessenger, InstanceManager instanceManager) {
+ @NonNull BinaryMessenger binaryMessenger, @NonNull InstanceManager instanceManager) {
super(binaryMessenger);
this.instanceManager = instanceManager;
}
diff --git a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraSelectorHostApiImpl.java b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraSelectorHostApiImpl.java
index 8ceafbcecc7b..bbd747342def 100644
--- a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraSelectorHostApiImpl.java
+++ b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraSelectorHostApiImpl.java
@@ -5,6 +5,7 @@
package io.flutter.plugins.camerax;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.camera.core.CameraInfo;
import androidx.camera.core.CameraSelector;
@@ -18,16 +19,16 @@ public class CameraSelectorHostApiImpl implements CameraSelectorHostApi {
private final BinaryMessenger binaryMessenger;
private final InstanceManager instanceManager;
- @VisibleForTesting public CameraXProxy cameraXProxy = new CameraXProxy();
+ @VisibleForTesting public @NonNull CameraXProxy cameraXProxy = new CameraXProxy();
public CameraSelectorHostApiImpl(
- BinaryMessenger binaryMessenger, InstanceManager instanceManager) {
+ @NonNull BinaryMessenger binaryMessenger, @NonNull InstanceManager instanceManager) {
this.binaryMessenger = binaryMessenger;
this.instanceManager = instanceManager;
}
@Override
- public void create(@NonNull Long identifier, Long lensFacing) {
+ public void create(@NonNull Long identifier, @Nullable Long lensFacing) {
CameraSelector.Builder cameraSelectorBuilder = cameraXProxy.createCameraSelectorBuilder();
if (lensFacing != null) {
cameraSelectorBuilder = cameraSelectorBuilder.requireLensFacing(lensFacing.intValue());
@@ -36,10 +37,10 @@ public void create(@NonNull Long identifier, Long lensFacing) {
}
@Override
- public List filter(@NonNull Long identifier, @NonNull List cameraInfoIds) {
+ public @NonNull List filter(@NonNull Long identifier, @NonNull List cameraInfoIds) {
CameraSelector cameraSelector =
(CameraSelector) Objects.requireNonNull(instanceManager.getInstance(identifier));
- List cameraInfosForFilter = new ArrayList();
+ List cameraInfosForFilter = new ArrayList<>();
for (Number cameraInfoAsNumber : cameraInfoIds) {
Long cameraInfoId = cameraInfoAsNumber.longValue();
@@ -50,7 +51,7 @@ public List filter(@NonNull Long identifier, @NonNull List cameraInf
}
List filteredCameraInfos = cameraSelector.filter(cameraInfosForFilter);
- List filteredCameraInfosIds = new ArrayList();
+ List filteredCameraInfosIds = new ArrayList<>();
for (CameraInfo cameraInfo : filteredCameraInfos) {
Long filteredCameraInfoId = instanceManager.getIdentifierForStrongReference(cameraInfo);
diff --git a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraStateErrorFlutterApiWrapper.java b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraStateErrorFlutterApiWrapper.java
new file mode 100644
index 000000000000..f4c8d6ee4afd
--- /dev/null
+++ b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraStateErrorFlutterApiWrapper.java
@@ -0,0 +1,57 @@
+// Copyright 2013 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.
+
+package io.flutter.plugins.camerax;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
+import androidx.camera.core.CameraState;
+import io.flutter.plugin.common.BinaryMessenger;
+import io.flutter.plugins.camerax.GeneratedCameraXLibrary.CameraStateErrorFlutterApi;
+
+/**
+ * Flutter API implementation for {@link CameraStateError}.
+ *
+ *
This class may handle adding native instances that are attached to a Dart instance or passing
+ * arguments of callbacks methods to a Dart instance.
+ */
+public class CameraStateErrorFlutterApiWrapper {
+ private final BinaryMessenger binaryMessenger;
+ private final InstanceManager instanceManager;
+ private CameraStateErrorFlutterApi cameraStateErrorFlutterApi;
+
+ /**
+ * Constructs a {@link CameraStateErrorFlutterApiWrapper}.
+ *
+ * @param binaryMessenger used to communicate with Dart over asynchronous messages
+ * @param instanceManager maintains instances stored to communicate with attached Dart objects
+ */
+ public CameraStateErrorFlutterApiWrapper(
+ @NonNull BinaryMessenger binaryMessenger, @NonNull InstanceManager instanceManager) {
+ this.binaryMessenger = binaryMessenger;
+ this.instanceManager = instanceManager;
+ cameraStateErrorFlutterApi = new CameraStateErrorFlutterApi(binaryMessenger);
+ }
+
+ /**
+ * Stores the {@link CameraStateError} instance and notifies Dart to create and store a new {@link
+ * CameraStateError} instance that is attached to this one. If {@code instance} has already been
+ * added, this method does nothing.
+ */
+ public void create(
+ @NonNull CameraState.StateError instance,
+ @NonNull Long code,
+ @NonNull CameraStateErrorFlutterApi.Reply callback) {
+ if (!instanceManager.containsInstance(instance)) {
+ cameraStateErrorFlutterApi.create(
+ instanceManager.addHostCreatedInstance(instance), code, callback);
+ }
+ }
+
+ /** Sets the Flutter API used to send messages to Dart. */
+ @VisibleForTesting
+ void setApi(@NonNull CameraStateErrorFlutterApi api) {
+ this.cameraStateErrorFlutterApi = api;
+ }
+}
diff --git a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraStateFlutterApiWrapper.java b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraStateFlutterApiWrapper.java
new file mode 100644
index 000000000000..cb1c30ad424e
--- /dev/null
+++ b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraStateFlutterApiWrapper.java
@@ -0,0 +1,102 @@
+// Copyright 2013 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.
+
+package io.flutter.plugins.camerax;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+import androidx.camera.core.CameraState;
+import io.flutter.plugin.common.BinaryMessenger;
+import io.flutter.plugins.camerax.GeneratedCameraXLibrary.CameraStateFlutterApi;
+import io.flutter.plugins.camerax.GeneratedCameraXLibrary.CameraStateType;
+import io.flutter.plugins.camerax.GeneratedCameraXLibrary.CameraStateTypeData;
+
+/**
+ * Flutter API implementation for {@link CameraState}.
+ *
+ *
This class may handle adding native instances that are attached to a Dart instance or passing
+ * arguments of callbacks methods to a Dart instance.
+ */
+public class CameraStateFlutterApiWrapper {
+ private final BinaryMessenger binaryMessenger;
+ private final InstanceManager instanceManager;
+ private CameraStateFlutterApi cameraStateFlutterApi;
+
+ /**
+ * Constructs a {@link CameraStateFlutterApiWrapper}.
+ *
+ * @param binaryMessenger used to communicate with Dart over asynchronous messages
+ * @param instanceManager maintains instances stored to communicate with attached Dart objects
+ */
+ public CameraStateFlutterApiWrapper(
+ @NonNull BinaryMessenger binaryMessenger, @NonNull InstanceManager instanceManager) {
+ this.binaryMessenger = binaryMessenger;
+ this.instanceManager = instanceManager;
+ cameraStateFlutterApi = new CameraStateFlutterApi(binaryMessenger);
+ }
+
+ /**
+ * Stores the {@link CameraState} instance and notifies Dart to create and store a new {@link
+ * CameraState} instance that is attached to this one. If {@code instance} has already been added,
+ * this method does nothing.
+ */
+ public void create(
+ @NonNull CameraState instance,
+ @NonNull CameraStateType type,
+ @Nullable CameraState.StateError error,
+ @NonNull CameraStateFlutterApi.Reply callback) {
+ if (instanceManager.containsInstance(instance)) {
+ return;
+ }
+
+ if (error != null) {
+ // if there is a problem with the current camera state, we need to create a CameraStateError
+ // to send to the Dart side.
+ new CameraStateErrorFlutterApiWrapper(binaryMessenger, instanceManager)
+ .create(error, Long.valueOf(error.getCode()), reply -> {});
+ }
+
+ cameraStateFlutterApi.create(
+ instanceManager.addHostCreatedInstance(instance),
+ new CameraStateTypeData.Builder().setValue(type).build(),
+ instanceManager.getIdentifierForStrongReference(error),
+ callback);
+ }
+
+ /** Converts CameraX CameraState.Type to CameraStateType that the Dart side understands. */
+ @NonNull
+ public static CameraStateType getCameraStateType(@NonNull CameraState.Type type) {
+ CameraStateType cameraStateType = null;
+ switch (type) {
+ case CLOSED:
+ cameraStateType = CameraStateType.CLOSED;
+ break;
+ case CLOSING:
+ cameraStateType = CameraStateType.CLOSING;
+ break;
+ case OPEN:
+ cameraStateType = CameraStateType.OPEN;
+ break;
+ case OPENING:
+ cameraStateType = CameraStateType.OPENING;
+ break;
+ case PENDING_OPEN:
+ cameraStateType = CameraStateType.PENDING_OPEN;
+ break;
+ }
+
+ if (cameraStateType == null) {
+ throw new IllegalArgumentException(
+ "The CameraState.Type passed to this method was not recognized.");
+ }
+ return cameraStateType;
+ }
+
+ /** Sets the Flutter API used to send messages to Dart. */
+ @VisibleForTesting
+ void setApi(@NonNull CameraStateFlutterApi api) {
+ this.cameraStateFlutterApi = api;
+ }
+}
diff --git a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraXProxy.java b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraXProxy.java
index da025b11dac2..af7fdc36a721 100644
--- a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraXProxy.java
+++ b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraXProxy.java
@@ -13,6 +13,7 @@
import androidx.camera.core.ImageAnalysis;
import androidx.camera.core.ImageCapture;
import androidx.camera.core.Preview;
+import androidx.camera.video.Recorder;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugins.camerax.GeneratedCameraXLibrary.ResolutionInfo;
import java.io.File;
@@ -23,45 +24,57 @@ public class CameraXProxy {
* Converts a {@link ResolutionInfo} instance to a {@link Size} for setting the target resolution
* of {@link UseCase}s.
*/
- public static Size sizeFromResolution(@NonNull ResolutionInfo resolutionInfo) {
+ public static @NonNull Size sizeFromResolution(@NonNull ResolutionInfo resolutionInfo) {
return new Size(resolutionInfo.getWidth().intValue(), resolutionInfo.getHeight().intValue());
}
- public CameraSelector.Builder createCameraSelectorBuilder() {
+ public @NonNull CameraSelector.Builder createCameraSelectorBuilder() {
return new CameraSelector.Builder();
}
- public CameraPermissionsManager createCameraPermissionsManager() {
+ /** Creates an instance of {@link CameraPermissionsManager}. */
+ public @NonNull CameraPermissionsManager createCameraPermissionsManager() {
return new CameraPermissionsManager();
}
- public DeviceOrientationManager createDeviceOrientationManager(
+ /** Creates an instance of the {@link DeviceOrientationManager}. */
+ public @NonNull DeviceOrientationManager createDeviceOrientationManager(
@NonNull Activity activity,
@NonNull Boolean isFrontFacing,
- @NonNull int sensorOrientation,
+ int sensorOrientation,
@NonNull DeviceOrientationManager.DeviceOrientationChangeCallback callback) {
return new DeviceOrientationManager(activity, isFrontFacing, sensorOrientation, callback);
}
- public Preview.Builder createPreviewBuilder() {
+ /** Creates a builder for an instance of the {@link Preview} use case. */
+ public @NonNull Preview.Builder createPreviewBuilder() {
return new Preview.Builder();
}
- public Surface createSurface(@NonNull SurfaceTexture surfaceTexture) {
+ /** Creates a {@link Surface} instance from the specified {@link SurfaceTexture}. */
+ public @NonNull Surface createSurface(@NonNull SurfaceTexture surfaceTexture) {
return new Surface(surfaceTexture);
}
/**
- * Creates an instance of the {@code SystemServicesFlutterApiImpl}.
+ * Creates an instance of the {@link SystemServicesFlutterApiImpl}.
*
*
Included in this class to utilize the callback methods it provides, e.g. {@code
* onCameraError(String)}.
*/
- public SystemServicesFlutterApiImpl createSystemServicesFlutterApiImpl(
+ public @NonNull SystemServicesFlutterApiImpl createSystemServicesFlutterApiImpl(
@NonNull BinaryMessenger binaryMessenger) {
return new SystemServicesFlutterApiImpl(binaryMessenger);
}
+ /** Creates an instance of {@link Recorder.Builder}. */
+ @NonNull
+ public Recorder.Builder createRecorderBuilder() {
+ return new Recorder.Builder();
+ }
+
+ /** Creates a builder for an instance of the {@link ImageCapture} use case. */
+ @NonNull
public ImageCapture.Builder createImageCaptureBuilder() {
return new ImageCapture.Builder();
}
diff --git a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/DeviceOrientationManager.java b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/DeviceOrientationManager.java
index ebcb86433f65..67cac560db4d 100644
--- a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/DeviceOrientationManager.java
+++ b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/DeviceOrientationManager.java
@@ -14,6 +14,7 @@
import android.view.Surface;
import android.view.WindowManager;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import io.flutter.embedding.engine.systemchannels.PlatformChannel;
import io.flutter.embedding.engine.systemchannels.PlatformChannel.DeviceOrientation;
@@ -106,7 +107,7 @@ public int getPhotoOrientation() {
* into degrees.
* @return The device's photo orientation in degrees.
*/
- public int getPhotoOrientation(PlatformChannel.DeviceOrientation orientation) {
+ public int getPhotoOrientation(@Nullable PlatformChannel.DeviceOrientation orientation) {
int angle = 0;
// Fallback to device orientation when the orientation value is null.
if (orientation == null) {
@@ -163,7 +164,7 @@ public int getVideoOrientation() {
* into degrees.
* @return The device's video orientation in clockwise degrees.
*/
- public int getVideoOrientation(PlatformChannel.DeviceOrientation orientation) {
+ public int getVideoOrientation(@Nullable PlatformChannel.DeviceOrientation orientation) {
int angle = 0;
// Fallback to device orientation when the orientation value is null.
@@ -194,7 +195,7 @@ public int getVideoOrientation(PlatformChannel.DeviceOrientation orientation) {
}
/** @return the last received UI orientation. */
- public PlatformChannel.DeviceOrientation getLastUIOrientation() {
+ public @Nullable PlatformChannel.DeviceOrientation getLastUIOrientation() {
return this.lastOrientation;
}
@@ -236,6 +237,8 @@ static void handleOrientationChange(
*
* @return The current user interface orientation.
*/
+ // Configuration.ORIENTATION_SQUARE is deprecated.
+ @SuppressWarnings("deprecation")
@VisibleForTesting
PlatformChannel.DeviceOrientation getUIOrientation() {
final int rotation = getDisplay().getRotation();
@@ -254,6 +257,8 @@ PlatformChannel.DeviceOrientation getUIOrientation() {
} else {
return PlatformChannel.DeviceOrientation.LANDSCAPE_RIGHT;
}
+ case Configuration.ORIENTATION_SQUARE:
+ case Configuration.ORIENTATION_UNDEFINED:
default:
return PlatformChannel.DeviceOrientation.PORTRAIT_UP;
}
diff --git a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/ExposureStateFlutterApiImpl.java b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/ExposureStateFlutterApiImpl.java
new file mode 100644
index 000000000000..1f31f603a8a4
--- /dev/null
+++ b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/ExposureStateFlutterApiImpl.java
@@ -0,0 +1,49 @@
+// Copyright 2013 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.
+
+package io.flutter.plugins.camerax;
+
+import android.util.Range;
+import androidx.annotation.NonNull;
+import androidx.camera.core.ExposureState;
+import io.flutter.plugin.common.BinaryMessenger;
+import io.flutter.plugins.camerax.GeneratedCameraXLibrary.ExposureCompensationRange;
+import io.flutter.plugins.camerax.GeneratedCameraXLibrary.ExposureStateFlutterApi;
+
+public class ExposureStateFlutterApiImpl extends ExposureStateFlutterApi {
+ private final InstanceManager instanceManager;
+
+ public ExposureStateFlutterApiImpl(
+ @NonNull BinaryMessenger binaryMessenger, @NonNull InstanceManager instanceManager) {
+ super(binaryMessenger);
+ this.instanceManager = instanceManager;
+ }
+
+ /**
+ * Creates a {@link ExposureState} on the Dart side with its exposure compensation range that can
+ * be used to set the exposure compensation index and its exposure compensation step, the smallest
+ * step by which the exposure compensation can be changed.
+ */
+ void create(@NonNull ExposureState exposureState, @NonNull Reply reply) {
+ if (instanceManager.containsInstance(exposureState)) {
+ return;
+ }
+
+ final Range exposureCompensationRangeFromState =
+ exposureState.getExposureCompensationRange();
+ ExposureCompensationRange exposureCompensationRange =
+ new ExposureCompensationRange.Builder()
+ .setMinCompensation(exposureCompensationRangeFromState.getLower().longValue())
+ .setMaxCompensation(exposureCompensationRangeFromState.getUpper().longValue())
+ .build();
+ final Double exposureCompensationStep =
+ exposureState.getExposureCompensationStep().doubleValue();
+
+ create(
+ instanceManager.addHostCreatedInstance(exposureState),
+ exposureCompensationRange,
+ exposureCompensationStep,
+ reply);
+ }
+}
diff --git a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/GeneratedCameraXLibrary.java b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/GeneratedCameraXLibrary.java
index 31cea4add1f1..c6f627993772 100644
--- a/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/GeneratedCameraXLibrary.java
+++ b/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/GeneratedCameraXLibrary.java
@@ -1,7 +1,7 @@
// Copyright 2013 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.
-// Autogenerated from Pigeon (v9.2.4), do not edit directly.
+// Autogenerated from Pigeon (v9.2.5), do not edit directly.
// See also: https://pub.dev/packages/pigeon
package io.flutter.plugins.camerax;
@@ -57,6 +57,36 @@ protected static ArrayList