diff --git a/.ci/dev/README.md b/.ci/dev/README.md new file mode 100644 index 000000000000..d266afbf2687 --- /dev/null +++ b/.ci/dev/README.md @@ -0,0 +1,19 @@ +This directory contains resources that the Flutter team uses during +the development of plugins. + +## Luci builder file +`try_builders.json` contains the supported luci try builders +for plugins. It follows format: +```json +{ + "builders":[ + { + "name":"yyy", + "repo":"plugins", + "enabled":true + } + ] +} +``` +This file will be mainly used in [`flutter/cocoon`](https://github.com/flutter/cocoon) +to trigger/update pre-submit luci tasks. diff --git a/.ci/dev/try_builders.json b/.ci/dev/try_builders.json new file mode 100644 index 000000000000..6334a3d64fa4 --- /dev/null +++ b/.ci/dev/try_builders.json @@ -0,0 +1,9 @@ +{ + "builders":[ + { + "name":"Windows Plugins", + "repo":"plugins", + "enabled":true + } + ] +} diff --git a/.cirrus.yml b/.cirrus.yml index d5a1ac82f6d5..a49a8b14ca83 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -14,7 +14,9 @@ task: - flutter channel master - flutter upgrade - git fetch origin master - activate_script: pub global activate flutter_plugin_tools + submodules_script: + - git submodule init + - git submodule update matrix: - name: publishable script: @@ -39,8 +41,16 @@ task: - flutter channel $CHANNEL - ./script/incremental_build.sh test - name: analyze + env: + matrix: + CHANNEL: "master" + CHANNEL: "stable" script: ./script/incremental_build.sh analyze - name: build_all_plugins_apk + env: + matrix: + CHANNEL: "master" + CHANNEL: "stable" script: # TODO(jackson): Allow web plugins once supported on stable # https://github.com/flutter/flutter/issues/42864 @@ -59,7 +69,7 @@ task: - ./chromedriver/chromedriver --port=4444 & test_script: - cd $INTEGRATION_TEST_PATH/example/ - - flutter drive -v --target=test_driver/example_integration.dart -d web-server --release --browser-name=chrome + - flutter drive -v --driver=test_driver/integration_test.dart --target=integration_test/example_test.dart -d web-server --release --browser-name=chrome - name: build-apks+java-test+firebase-test-lab env: matrix: @@ -114,7 +124,9 @@ task: - flutter channel master - flutter upgrade - git fetch origin master - activate_script: pub global activate flutter_plugin_tools + submodules_script: + - git submodule init + - git submodule update matrix: - name: build-linux+drive-examples install_script: @@ -126,43 +138,41 @@ task: - xvfb-run ./script/incremental_build.sh drive-examples --linux task: + # Xcode 12 task # don't run on release tags since it creates O(n^2) tasks where n is the number of plugins only_if: $CIRRUS_TAG == '' use_compute_credits: $CIRRUS_USER_COLLABORATOR == 'true' osx_instance: - image: catalina-xcode-11.3.1-flutter + image: big-sur-xcode-12.3 upgrade_script: + - sudo gem install cocoapods - flutter channel stable - flutter upgrade - flutter channel master - flutter upgrade - git fetch origin master - activate_script: pub global activate flutter_plugin_tools + submodules_script: + - git submodule init + - git submodule update create_simulator_script: - xcrun simctl list - - xcrun simctl create Flutter-iPhone com.apple.CoreSimulator.SimDeviceType.iPhone-X com.apple.CoreSimulator.SimRuntime.iOS-13-3 | xargs xcrun simctl boot + - xcrun simctl create Flutter-iPhone com.apple.CoreSimulator.SimDeviceType.iPhone-11 com.apple.CoreSimulator.SimRuntime.iOS-14-3 | xargs xcrun simctl boot matrix: - name: build_all_plugins_ipa + env: + matrix: + CHANNEL: "master" + CHANNEL: "stable" script: # TODO(jackson): Allow web plugins once supported on stable # https://github.com/flutter/flutter/issues/42864 - if [[ "$CHANNEL" -eq "stable" ]]; then find . | grep _web$ | xargs rm -rf; fi - flutter channel $CHANNEL - ./script/build_all_plugins_app.sh ios --no-codesign - - name: lint_darwin_plugins - env: - matrix: - PLUGIN_SHARDING: "--shardIndex 0 --shardCount 2" - PLUGIN_SHARDING: "--shardIndex 1 --shardCount 2" - script: - # TODO(jmagman): Lint macOS podspecs but skip any that fail library validation. - - find . -name "*.podspec" | xargs grep -l "osx" | xargs rm - # Skip the dummy podspecs used to placate the tool. - - find . -name "*_web*.podspec" -o -name "*_mac*.podspec" | xargs rm - - ./script/incremental_build.sh podspecs - name: build-ipas+drive-examples env: PATH: $PATH:/usr/local/bin + PLUGINS_TO_SKIP_XCTESTS: "battery/battery,camera/camera,connectivity/connectivity,device_info/device_info,espresso,google_maps_flutter/google_maps_flutter,google_sign_in/google_sign_in,in_app_purchase,integration_test,ios_platform_images,local_auth,package_info,path_provider/path_provider,quick_actions,sensors,shared_preferences/shared_preferences,url_launcher/url_launcher,video_player/video_player,webview_flutter,wifi_info_flutter/wifi_info_flutter" matrix: PLUGIN_SHARDING: "--shardIndex 0 --shardCount 4" PLUGIN_SHARDING: "--shardIndex 1 --shardCount 4" @@ -177,21 +187,61 @@ task: # https://github.com/flutter/flutter/issues/42864 - if [[ "$CHANNEL" -eq "stable" ]]; then find . | grep _web$ | xargs rm -rf; fi - flutter channel $CHANNEL + - flutter upgrade - ./script/incremental_build.sh build-examples --ipa - ./script/incremental_build.sh drive-examples + - ./script/incremental_build.sh xctest --target RunnerUITests --skip $PLUGINS_TO_SKIP_XCTESTS --ios-destination "platform=iOS Simulator,name=iPhone 11,OS=14.3" + task: + # Xcode 11 task + # TODO(cyanglaz): merge Xcode 11 task to Xcode 12 task when all the matrix can be run in Xcode 12. # don't run on release tags since it creates O(n^2) tasks where n is the number of plugins only_if: $CIRRUS_TAG == '' use_compute_credits: $CIRRUS_USER_COLLABORATOR == 'true' osx_instance: image: catalina-xcode-11.3.1-flutter + upgrade_script: + - sudo gem install cocoapods + - flutter channel stable + - flutter upgrade + - flutter channel master + - flutter upgrade + - git fetch origin master + submodules_script: + - git submodule init + - git submodule update + create_simulator_script: + - xcrun simctl list + - xcrun simctl create Flutter-iPhone com.apple.CoreSimulator.SimDeviceType.iPhone-X com.apple.CoreSimulator.SimRuntime.iOS-13-3 | xargs xcrun simctl boot + matrix: + - name: lint_darwin_plugins + env: + matrix: + PLUGIN_SHARDING: "--shardIndex 0 --shardCount 2" + PLUGIN_SHARDING: "--shardIndex 1 --shardCount 2" + script: + # TODO(jmagman): Lint macOS podspecs but skip any that fail library validation. + - find . -name "*.podspec" | xargs grep -l "osx" | xargs rm + # Skip the dummy podspecs used to placate the tool. + - find . -name "*_web*.podspec" -o -name "*_mac*.podspec" | xargs rm + - ./script/incremental_build.sh podspecs + +task: + # don't run on release tags since it creates O(n^2) tasks where n is the number of plugins + only_if: $CIRRUS_TAG == '' + use_compute_credits: $CIRRUS_USER_COLLABORATOR == 'true' + osx_instance: + image: big-sur-xcode-12.3 setup_script: - flutter config --enable-macos-desktop upgrade_script: + - sudo gem install cocoapods - flutter channel master - flutter upgrade - git fetch origin master - activate_script: pub global activate flutter_plugin_tools + submodules_script: + - git submodule init + - git submodule update matrix: - name: build_all_plugins_app script: diff --git a/.clang-format b/.clang-format new file mode 100644 index 000000000000..f6cb8ad931f5 --- /dev/null +++ b/.clang-format @@ -0,0 +1 @@ +BasedOnStyle: Google diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 083e125b32d2..741216982d35 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,37 +1,32 @@ -## Description +*Replace this paragraph with a description of what this PR is changing or adding, and why. Consider including before/after screenshots.* -*Replace this paragraph with a description of what this PR is doing. If you're modifying existing behavior, describe the existing behavior, how this PR is changing it, and what motivated the change.* +*List which issues are fixed by this PR. You must list at least one issue.* -## Related Issues +*If you had to change anything in the [flutter/tests] repo, include a link to the migration guide as per the [breaking change policy].* -*Replace this paragraph with a list of issues related to this PR from the [issue database](https://github.com/flutter/flutter/issues). Indicate, which of these issues are resolved or fixed by this PR. Note that you'll have to prefix the issue numbers with flutter/flutter#.* - -## Checklist - -Before you create this PR confirm that it meets all requirements listed below by checking the relevant checkboxes (`[x]`). This will ensure a smooth and quick review process. +## Pre-launch Checklist +- [ ] The title of the PR starts with the name of the plugin surrounded by square brackets, e.g. `[shared_preferences]` - [ ] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. -- [ ] My PR includes unit or integration tests for *all* changed/updated/fixed behaviors (See [Contributor Guide]). -- [ ] All existing and new tests are passing. -- [ ] I updated/added relevant documentation (doc comments with `///`). -- [ ] The analyzer (`flutter analyze`) does not report any problems on my PR. -- [ ] I read and followed the [Flutter Style Guide]. -- [ ] The title of the PR starts with the name of the plugin surrounded by square brackets, e.g. [shared_preferences] +- [ ] I read the [Tree Hygiene] wiki page, which explains my responsibilities. +- [ ] I read and followed the [Flutter Style Guide] and the [C++, Objective-C, Java style guides]. +- [ ] I listed at least one issue that this PR fixes in the description above. +- [ ] I added new tests to check the change I am making or feature I am adding, or Hixie said the PR is test exempt. - [ ] I updated pubspec.yaml with an appropriate new version according to the [pub versioning philosophy]. - [ ] I updated CHANGELOG.md to add a description of the change. +- [ ] I updated/added relevant documentation (doc comments with `///`). - [ ] I signed the [CLA]. -- [ ] I am willing to follow-up on review comments in a timely manner. - -## Breaking Change - -Does your PR require plugin users to manually update their apps to accommodate your change? +- [ ] All existing and new tests are passing. -- [ ] Yes, this is a breaking change (please indicate a breaking change in CHANGELOG.md and increment major revision). -- [ ] No, this is *not* a breaking change. +If you need help, consider asking for advice on the #hackers-new channel on [Discord]. -[issue database]: https://github.com/flutter/flutter/issues -[Contributor Guide]: https://github.com/flutter/plugins/blob/master/CONTRIBUTING.md +[Contributor Guide]: https://github.com/flutter/flutter/wiki/Tree-hygiene#overview +[Tree Hygiene]: https://github.com/flutter/flutter/wiki/Tree-hygiene [Flutter Style Guide]: https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo -[pub versioning philosophy]: https://www.dartlang.org/tools/pub/versioning +[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/master/CONTRIBUTING.md#style [CLA]: https://cla.developers.google.com/ +[flutter/tests]: https://github.com/flutter/tests +[breaking change policy]: https://github.com/flutter/flutter/wiki/Tree-hygiene#handling-breaking-changes +[Discord]: https://github.com/flutter/flutter/wiki/Chat +[pub versioning philosophy]: https://dart.dev/tools/pub/versioning diff --git a/.github/labeler.yml b/.github/labeler.yml new file mode 100644 index 000000000000..cdb9ade0e7f8 --- /dev/null +++ b/.github/labeler.yml @@ -0,0 +1,110 @@ +'p: android_alarm_manager': + - packages/android_alarm_manager/**/* + +'p: android_intent': + - packages/android_intent/**/* + +'p: battery': + - packages/battery/**/* + +'p: camera': + - packages/camera/**/* + +'p: connectivity': + - packages/connectivity/**/* + +'p: cross_file': + - packages/cross_file/**/* + +'p: device_info': + - packages/device_info/**/* + +'p: e2e': + - packages/e2e/**/* + +'p: espresso': + - packages/espresso/**/* + +'p: file_selector': + - packages/file_selector/**/* + +'p: flutter_plugin_android_lifecycle': + - packages/flutter_plugin_android_lifecycle/**/* + +'p: google_maps_flutter': + - packages/google_maps_flutter/**/* + +'p: google_sign_in': + - packages/google_sign_in/**/* + +'p: image_picker': + - packages/image_picker/**/* + +'p: in_app_purchase': + - packages/in_app_purchase/**/* + +'p: integration_test': + - packages/integration_test/**/* + +'p: ios_platform_images': + - packages/ios_platform_images/**/* + +'p: local_auth': + - packages/local_auth/**/* + +'p: package_info': + - packages/package_info/**/* + +'p: path_provider': + - packages/path_provider/**/* + +'p: plugin_platform_interface': + - packages/plugin_platform_interface/**/* + +'p: quick_actions': + - packages/quick_actions/**/* + +'p: sensors': + - packages/sensors/**/* + +'p: share': + - packages/share/**/* + +'p: shared_preferences': + - packages/shared_preferences/**/* + +'p: url_launcher': + - packages/url_launcher/**/* + +'p: video_player': + - packages/video_player/**/* + +'p: webview_flutter': + - packages/webview_flutter/**/* + +'p: wifi_info_flutter': + - packages/wifi_info_flutter/**/* + +'platform-android': + - packages/*/*_android/**/* + - packages/**/android/**/* + +'platform-ios': + - packages/*/*_ios/**/* + - packages/**/ios/**/* + +'platform-linux': + - packages/*/*_linux/**/* + - packages/**/linux/**/* + +'platform-macos': + - packages/*/*_macos/**/* + - packages/**/macos/**/* + +'platform-web': + - packages/*/*_web/**/* + - packages/**/web/**/* + +'platform-windows': + - packages/*/*_windows/**/* + - packages/**/windows/**/* diff --git a/.github/post_merge_labeler.yml b/.github/post_merge_labeler.yml new file mode 100644 index 000000000000..c02eb411773e --- /dev/null +++ b/.github/post_merge_labeler.yml @@ -0,0 +1,2 @@ +'needs-publishing': + - packages/*/** diff --git a/.github/workflows/pull_request_label.yml b/.github/workflows/pull_request_label.yml new file mode 100644 index 000000000000..7b048d33e669 --- /dev/null +++ b/.github/workflows/pull_request_label.yml @@ -0,0 +1,31 @@ +# This workflow applies labels to pull requests based on the +# paths that are modified in the pull request. +# +# Edit `.github/labeler.yml` and `.github/post_merge_labeler.yml` +# to configure labels. +# +# For more information, see: https://github.com/actions/labeler + +name: Pull Request Labeler + +on: + pull_request_target: + types: [opened, synchronize, reopened, closed] + +jobs: + label: + runs-on: ubuntu-latest + steps: + - uses: actions/labeler@v3 + with: + repo-token: "${{ secrets.GITHUB_TOKEN }}" + sync-labels: true + + post_merge_label: + if: github.event.action == 'closed' && github.event.pull_request.merged == true + runs-on: ubuntu-latest + steps: + - uses: actions/labeler@v3 + with: + repo-token: "${{ secrets.GITHUB_TOKEN }}" + configuration-path: .github/post_merge_labeler.yml diff --git a/.gitignore b/.gitignore index 88ce490e4701..d7560505f166 100644 --- a/.gitignore +++ b/.gitignore @@ -37,6 +37,7 @@ gradle-wrapper.jar generated_plugin_registrant.dart GeneratedPluginRegistrant.h GeneratedPluginRegistrant.m +generated_plugin_registrant.cc GeneratedPluginRegistrant.java GeneratedPluginRegistrant.swift build/ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 000000000000..d83ab14b23a0 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "script/plugin_tools"] + path = script/plugin_tools + url = https://github.com/flutter/plugin_tools.git diff --git a/AUTHORS b/AUTHORS index 51345c9a3481..1f2b9cba2f16 100644 --- a/AUTHORS +++ b/AUTHORS @@ -59,3 +59,6 @@ Kazuki Yamaguchi Eitan Schwartz Chris Rutkowski Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li diff --git a/CODEOWNERS b/CODEOWNERS index 97f8bf388697..01732888ad89 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -4,22 +4,12 @@ # These names are just suggestions. It is fine to have your changes # reviewed by someone else. -packages/android_alarm_manager/* @bkonyi -packages/android_intent/* @mklim @matthew-carroll -packages/battery/* @amirh @matthew-carroll -packages/camera/* @bparrishMines -packages/connectivity/* @cyanglaz @matthew-carroll -packages/device_info/* @matthew-carroll -packages/espresso/* @collinjackson @adazh -packages/google_maps_flutter/* @cyanglaz -packages/google_sign_in/* @cyanglaz @mehmetf -packages/image_picker/* @cyanglaz -packages/integration_test/* @dnfield -packages/in_app_purchase/* @mklim @cyanglaz @LHLL -packages/ios_platform_images/* @gaaclarke -packages/package_info/* @cyanglaz @matthew-carroll -packages/path_provider/* @matthew-carroll -packages/shared_preferences/* @matthew-carroll -packages/url_launcher/* @mklim -packages/video_player/* @iskakaushik @cyanglaz -packages/webview_flutter/* @amirh + +packages/camera/** @bparrishMines +packages/cross_file/** @ditman @mvanbeusekom +packages/file_selector/** @ditman +packages/google_maps_flutter/** @cyanglaz +packages/image_picker/** @cyanglaz +packages/integration_test/** @dnfield +packages/in_app_purchase/** @cyanglaz @LHLL +packages/ios_platform_images/** @gaaclarke diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f58dfea6a065..6c4abd0cb516 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -3,7 +3,26 @@ [![Build Status](https://api.cirrus-ci.com/github/flutter/plugins.svg)](https://cirrus-ci.com/github/flutter/plugins/master) -_See also: [Flutter's code of conduct](https://flutter.io/design-principles/#code-of-conduct)_ +_See also: [Flutter's code of conduct](https://github.com/flutter/flutter/blob/master/CODE_OF_CONDUCT.md)_ + +## Important note + +As of January 2021, we are no longer accepting non-critical PRs for plugins +for which there is a corresponding [Flutter Community Plus +Plugin](https://plus.fluttercommunity.dev/), as we hope in time to be able +to transition users to those versions of the plugins. If you have a PR for +something other than a critical issue (crashes, build failures, null safety, etc.) +for any of the following plugins, we encourage you to submit it +[there](https://github.com/fluttercommunity/plus_plugins/pulls) instead: +- `android_alarm_manager` +- `android_intent` +- `battery` +- `connectivity` +- `device_info` +- `package_info` +- `sensors` +- `share` +- `wifi_info_flutter` (corresponds to `network_info_plus`) ## Things you will need @@ -40,6 +59,28 @@ USB and debugging enabled on that device. * `cd packages/battery/example` * `flutter run` +## Setting up XCUITests + +Sometimes, XCUITests are useful when integration testing a plugin that has native UI on iOS (e.g image_picker, in_app_purchase, camera, share, local_auth etc). Most of the time, XCUITests are not necessary, consider using [integration_test](https://pub.dev/packages/integration_test) if the tests are not focused on iOS system UI. + +If XCUITests has always been set up for the plugin, a RunnerUITests folder under `/example/ios` directory can be found. +If XCUITests has not been set up for the plugin, follow these steps to set it up: + +1. Open /example/ios/Runner.xcworkspace using XCode. +1. Create a new "UI Testing Bundle". +1. In the target options window, populate details as following, then click on "Finish". + * In the "product name" field, type in "RunnerUITests" (this is the test target name our CI looks for.). + * In the "Team" field, select "None". + * In the Organization Name field, type in "Flutter". This should usually be pre-populated. + * In the organization identifer field, type in "com.google". This should usually be pre-populated. + * In the Language field, select "Objective-C". + * In the Project field, select the xcodeproj "Runner" (blue color). + * In the Target to be Tested, select xcworkspace "Runner" (white color). +1. A RunnerUITests folder should be created and you can start hacking in `RunnerUITests.m`. +1. To enable the test on CI, the plugin needs to be removed from the "skip" list: + * Open `./cirrus.yml` and find PLUGINS_TO_SKIP_XCTESTS. + * Remove the plugin name from the list. + ## Running the tests ### Integration tests @@ -84,14 +125,33 @@ cd android ./gradlew test ``` +### XCTests (iOS) + +XCUnitTests are typically configured to run with cocoapods in this repo. To run all the XCUnitTests for a plugin: + +```console +cd ios +pod lib lint --allow-warnings +``` + +XCUITests aren't usually configured with cocoapods in this repo. They are configured in a xcode workspace target named RunnerUITests. +To run all the XCUITests in a plugin, follow the steps in a regular iOS development workflow [here](https://developer.apple.com/library/archive/documentation/DeveloperTools/Conceptual/testing_with_xcode/chapters/05-running_tests.html) + +For convenience, a [flutter_plugin_tools](https://pub.dev/packages/flutter_plugin_tools) command `xctest` could also be used to run all the XCUITests in the repo: + +```console +pub global activate flutter_plugin_tools +cd /packages +pub global run flutter_plugin_tools xctest --target RunnerUITests --skip +``` + ## Contributing code We gladly accept contributions via GitHub pull requests. Please peruse our -[style guide](https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo) and -[design principles](https://flutter.io/design-principles/) before -working on anything non-trivial. These guidelines are intended to +[style guide](https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo) +before working on anything non-trivial. These guidelines are intended to keep the code consistent and avoid common pitfalls. To start working on a patch: @@ -99,7 +159,7 @@ To start working on a patch: * `git fetch upstream` * `git checkout upstream/master -b ` * Hack away. - * Verify changes with [flutter_plugin_tools](https://pub.dartlang.org/packages/flutter_plugin_tools) + * Verify changes with [flutter_plugin_tools](https://pub.dev/packages/flutter_plugin_tools) ``` pub global activate flutter_plugin_tools pub global run flutter_plugin_tools format --plugins plugin_name diff --git a/LICENSE b/LICENSE index 7b995420294b..a6d6c0749818 100644 --- a/LICENSE +++ b/LICENSE @@ -1,27 +1,25 @@ Copyright 2017 The Chromium Authors. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md index b2015a705e79..b65c10e7f381 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,9 @@ These plugins are also available on Please file any issues, bugs, or feature requests in the [main flutter repo](https://github.com/flutter/flutter/issues/new). +Issues pertaining to this repository are [labeled +"plugin"](https://github.com/flutter/flutter/issues?q=is%3Aopen+is%3Aissue+label%3Aplugin). + ## Contributing If you wish to contribute a new plugin to the Flutter ecosystem, please @@ -36,31 +39,31 @@ and send a [pull request](https://github.com/flutter/plugins/pulls). ## Plugins These are the available plugins in this repository. -| Plugin | Pub | -|--------|-----| -| [android_alarm_manager](./packages/android_alarm_manager/) | [![pub package](https://img.shields.io/pub/v/android_alarm_manager.svg)](https://pub.dev/packages/android_alarm_manager) | -| [android_intent](./packages/android_intent/) | [![pub package](https://img.shields.io/pub/v/android_intent.svg)](https://pub.dev/packages/android_intent) | -| [battery](./packages/battery/) | [![pub package](https://img.shields.io/pub/v/battery.svg)](https://pub.dev/packages/battery) | -| [camera](./packages/camera/) | [![pub package](https://img.shields.io/pub/v/camera.svg)](https://pub.dev/packages/camera) | -| [connectivity](./packages/connectivity/) | [![pub package](https://img.shields.io/pub/v/connectivity.svg)](https://pub.dev/packages/connectivity) | -| [device_info](./packages/device_info/) | [![pub package](https://img.shields.io/pub/v/device_info.svg)](https://pub.dev/packages/device_info) | -| [e2e (Discontinued, use integration_test)](./packages/e2e/) | [![pub package](https://img.shields.io/pub/v/e2e.svg)](https://pub.dev/packages/e2e) | -| [espresso](./packages/espresso/) | [![pub package](https://img.shields.io/pub/v/espresso.svg)](https://pub.dev/packages/espresso) | -| [flutter_plugin_android_lifecycle](./packages/flutter_plugin_android_lifecycle/) | [![pub package](https://img.shields.io/pub/v/flutter_plugin_android_lifecycle.svg)](https://pub.dev/packages/flutter_plugin_android_lifecycle) | -| [google_maps_flutter](./packages/google_maps_flutter) | [![pub package](https://img.shields.io/pub/v/google_maps_flutter.svg)](https://pub.dev/packages/google_maps_flutter) | -| [google_sign_in](./packages/google_sign_in/) | [![pub package](https://img.shields.io/pub/v/google_sign_in.svg)](https://pub.dev/packages/google_sign_in) | -| [image_picker](./packages/image_picker/) | [![pub package](https://img.shields.io/pub/v/image_picker.svg)](https://pub.dev/packages/image_picker) | -| [integration_test](./packages/integration_test/) | [![pub package](https://img.shields.io/pub/v/integration_test.svg)](https://pub.dev/packages/integration_test) | -| [in_app_purchase](./packages/in_app_purchase/) | [![pub package](https://img.shields.io/pub/v/in_app_purchase.svg)](https://pub.dev/packages/in_app_purchase) | -| [ios_platform_images](./packages/ios_platform_images/) | [![pub package](https://img.shields.io/pub/v/ios_platform_images.svg)](https://pub.dev/packages/ios_platform_images) | -| [local_auth](./packages/local_auth/) | [![pub package](https://img.shields.io/pub/v/local_auth.svg)](https://pub.dev/packages/local_auth) | -| [package_info](./packages/package_info/) | [![pub package](https://img.shields.io/pub/v/package_info.svg)](https://pub.dev/packages/package_info) | -| [path_provider](./packages/path_provider/) | [![pub package](https://img.shields.io/pub/v/path_provider.svg)](https://pub.dev/packages/path_provider) | -| [plugin_platform_interface](./packages/plugin_platform_interface/) | [![pub package](https://img.shields.io/pub/v/plugin_platform_interface.svg)](https://pub.dev/packages/plugin_platform_interface) | -| [quick_actions](./packages/quick_actions/) | [![pub package](https://img.shields.io/pub/v/quick_actions.svg)](https://pub.dev/packages/quick_actions) | -| [sensors](./packages/sensors/) | [![pub package](https://img.shields.io/pub/v/sensors.svg)](https://pub.dev/packages/sensors) | -| [share](./packages/share/) | [![pub package](https://img.shields.io/pub/v/share.svg)](https://pub.dev/packages/share) | -| [shared_preferences](./packages/shared_preferences/) | [![pub package](https://img.shields.io/pub/v/shared_preferences.svg)](https://pub.dev/packages/shared_preferences) | -| [url_launcher](./packages/url_launcher/) | [![pub package](https://img.shields.io/pub/v/url_launcher.svg)](https://pub.dev/packages/url_launcher) | -| [video_player](./packages/video_player/) | [![pub package](https://img.shields.io/pub/v/video_player.svg)](https://pub.dev/packages/video_player) | -| [webview_flutter](./packages/webview_flutter/) | [![pub package](https://img.shields.io/pub/v/webview_flutter.svg)](https://pub.dev/packages/webview_flutter) | +| Plugin | Pub | Points | Popularity | Likes | +|--------|-----|--------|------------|-------| +| [android_alarm_manager](./packages/android_alarm_manager/) | [![pub package](https://img.shields.io/pub/v/android_alarm_manager.svg)](https://pub.dev/packages/android_alarm_manager) | [![pub points](https://badges.bar/android_alarm_manager/pub%20points)](https://pub.dev/packages/android_alarm_manager/score) | [![popularity](https://badges.bar/android_alarm_manager/popularity)](https://pub.dev/packages/android_alarm_manager/score) | [![likes](https://badges.bar/android_alarm_manager/likes)](https://pub.dev/packages/android_alarm_manager/score) | +| [android_intent](./packages/android_intent/) | [![pub package](https://img.shields.io/pub/v/android_intent.svg)](https://pub.dev/packages/android_intent) | [![pub points](https://badges.bar/android_intent/pub%20points)](https://pub.dev/packages/android_intent/score) | [![popularity](https://badges.bar/android_intent/popularity)](https://pub.dev/packages/android_intent/score) | [![likes](https://badges.bar/android_intent/likes)](https://pub.dev/packages/android_intent/score) | +| [battery](./packages/battery/) | [![pub package](https://img.shields.io/pub/v/battery.svg)](https://pub.dev/packages/battery) | [![pub points](https://badges.bar/battery/pub%20points)](https://pub.dev/packages/battery/score) | [![popularity](https://badges.bar/battery/popularity)](https://pub.dev/packages/battery/score) | [![likes](https://badges.bar/battery/likes)](https://pub.dev/packages/battery/score) | +| [camera](./packages/camera/) | [![pub package](https://img.shields.io/pub/v/camera.svg)](https://pub.dev/packages/camera) | [![pub points](https://badges.bar/camera/pub%20points)](https://pub.dev/packages/camera/score) | [![popularity](https://badges.bar/camera/popularity)](https://pub.dev/packages/camera/score) | [![likes](https://badges.bar/camera/likes)](https://pub.dev/packages/camera/score) | +| [connectivity](./packages/connectivity/) | [![pub package](https://img.shields.io/pub/v/connectivity.svg)](https://pub.dev/packages/connectivity) | [![pub points](https://badges.bar/connectivity/pub%20points)](https://pub.dev/packages/connectivity/score) | [![popularity](https://badges.bar/connectivity/popularity)](https://pub.dev/packages/connectivity/score) | [![likes](https://badges.bar/connectivity/likes)](https://pub.dev/packages/connectivity/score) | +| [device_info](./packages/device_info/) | [![pub package](https://img.shields.io/pub/v/device_info.svg)](https://pub.dev/packages/device_info) | [![pub points](https://badges.bar/device_info/pub%20points)](https://pub.dev/packages/device_info/score) | [![popularity](https://badges.bar/device_info/popularity)](https://pub.dev/packages/device_info/score) | [![likes](https://badges.bar/device_info/likes)](https://pub.dev/packages/device_info/score) | +| [e2e (Discontinued, use integration_test)](./packages/e2e/) | [![pub package](https://img.shields.io/pub/v/e2e.svg)](https://pub.dev/packages/e2e) | [![pub points](https://badges.bar/e2e/pub%20points)](https://pub.dev/packages/e2e/score) | [![popularity](https://badges.bar/e2e/popularity)](https://pub.dev/packages/e2e/score) | [![likes](https://badges.bar/e2e/likes)](https://pub.dev/packages/e2e/score) | +| [espresso](./packages/espresso/) | [![pub package](https://img.shields.io/pub/v/espresso.svg)](https://pub.dev/packages/espresso) | [![pub points](https://badges.bar/espresso/pub%20points)](https://pub.dev/packages/espresso/score) | [![popularity](https://badges.bar/espresso/popularity)](https://pub.dev/packages/espresso/score) | [![likes](https://badges.bar/espresso/likes)](https://pub.dev/packages/espresso/score) | +| [flutter_plugin_android_lifecycle](./packages/flutter_plugin_android_lifecycle/) | [![pub package](https://img.shields.io/pub/v/flutter_plugin_android_lifecycle.svg)](https://pub.dev/packages/flutter_plugin_android_lifecycle) | [![pub points](https://badges.bar/flutter_plugin_android_lifecycle/pub%20points)](https://pub.dev/packages/flutter_plugin_android_lifecycle/score) | [![popularity](https://badges.bar/flutter_plugin_android_lifecycle/popularity)](https://pub.dev/packages/flutter_plugin_android_lifecycle/score) | [![likes](https://badges.bar/flutter_plugin_android_lifecycle/likes)](https://pub.dev/packages/flutter_plugin_android_lifecycle/score) | +| [google_maps_flutter](./packages/google_maps_flutter) | [![pub package](https://img.shields.io/pub/v/google_maps_flutter.svg)](https://pub.dev/packages/google_maps_flutter) | [![pub points](https://badges.bar/google_maps_flutter/pub%20points)](https://pub.dev/packages/google_maps_flutter/score) | [![popularity](https://badges.bar/google_maps_flutter/popularity)](https://pub.dev/packages/google_maps_flutter/score) | [![likes](https://badges.bar/google_maps_flutter/likes)](https://pub.dev/packages/google_maps_flutter/score) | +| [google_sign_in](./packages/google_sign_in/) | [![pub package](https://img.shields.io/pub/v/google_sign_in.svg)](https://pub.dev/packages/google_sign_in) | [![pub points](https://badges.bar/google_sign_in/pub%20points)](https://pub.dev/packages/google_sign_in/score) | [![popularity](https://badges.bar/google_sign_in/popularity)](https://pub.dev/packages/google_sign_in/score) | [![likes](https://badges.bar/google_sign_in/likes)](https://pub.dev/packages/google_sign_in/score) | +| [image_picker](./packages/image_picker/) | [![pub package](https://img.shields.io/pub/v/image_picker.svg)](https://pub.dev/packages/image_picker) | [![pub points](https://badges.bar/image_picker/pub%20points)](https://pub.dev/packages/image_picker/score) | [![popularity](https://badges.bar/image_picker/popularity)](https://pub.dev/packages/image_picker/score) | [![likes](https://badges.bar/image_picker/likes)](https://pub.dev/packages/image_picker/score) | +| [integration_test](./packages/integration_test/) | [![pub package](https://img.shields.io/pub/v/integration_test.svg)](https://pub.dev/packages/integration_test) | [![pub points](https://badges.bar/integration_test/pub%20points)](https://pub.dev/packages/integration_test/score) | [![popularity](https://badges.bar/integration_test/popularity)](https://pub.dev/packages/integration_test/score) | [![likes](https://badges.bar/integration_test/likes)](https://pub.dev/packages/integration_test/score) | +| [in_app_purchase](./packages/in_app_purchase/) | [![pub package](https://img.shields.io/pub/v/in_app_purchase.svg)](https://pub.dev/packages/in_app_purchase) | [![pub points](https://badges.bar/in_app_purchase/pub%20points)](https://pub.dev/packages/in_app_purchase/score) | [![popularity](https://badges.bar/in_app_purchase/popularity)](https://pub.dev/packages/in_app_purchase/score) | [![likes](https://badges.bar/in_app_purchase/likes)](https://pub.dev/packages/in_app_purchase/score) | +| [ios_platform_images](./packages/ios_platform_images/) | [![pub package](https://img.shields.io/pub/v/ios_platform_images.svg)](https://pub.dev/packages/ios_platform_images) | [![pub points](https://badges.bar/ios_platform_images/pub%20points)](https://pub.dev/packages/ios_platform_images/score) | [![popularity](https://badges.bar/ios_platform_images/popularity)](https://pub.dev/packages/ios_platform_images/score) | [![likes](https://badges.bar/ios_platform_images/likes)](https://pub.dev/packages/ios_platform_images/score) | +| [local_auth](./packages/local_auth/) | [![pub package](https://img.shields.io/pub/v/local_auth.svg)](https://pub.dev/packages/local_auth) | [![pub points](https://badges.bar/local_auth/pub%20points)](https://pub.dev/packages/local_auth/score) | [![popularity](https://badges.bar/local_auth/popularity)](https://pub.dev/packages/local_auth/score) | [![likes](https://badges.bar/local_auth/likes)](https://pub.dev/packages/local_auth/score) | +| [package_info](./packages/package_info/) | [![pub package](https://img.shields.io/pub/v/package_info.svg)](https://pub.dev/packages/package_info) | [![pub points](https://badges.bar/package_info/pub%20points)](https://pub.dev/packages/package_info/score) | [![popularity](https://badges.bar/package_info/popularity)](https://pub.dev/packages/package_info/score) | [![likes](https://badges.bar/package_info/likes)](https://pub.dev/packages/package_info/score) | +| [path_provider](./packages/path_provider/) | [![pub package](https://img.shields.io/pub/v/path_provider.svg)](https://pub.dev/packages/path_provider) | [![pub points](https://badges.bar/path_provider/pub%20points)](https://pub.dev/packages/path_provider/score) | [![popularity](https://badges.bar/path_provider/popularity)](https://pub.dev/packages/path_provider/score) | [![likes](https://badges.bar/path_provider/likes)](https://pub.dev/packages/path_provider/score) | +| [plugin_platform_interface](./packages/plugin_platform_interface/) | [![pub package](https://img.shields.io/pub/v/plugin_platform_interface.svg)](https://pub.dev/packages/plugin_platform_interface) | [![pub points](https://badges.bar/plugin_platform_interface/pub%20points)](https://pub.dev/packages/plugin_platform_interface/score) | [![popularity](https://badges.bar/plugin_platform_interface/popularity)](https://pub.dev/packages/plugin_platform_interface/score) | [![likes](https://badges.bar/plugin_platform_interface/likes)](https://pub.dev/packages/plugin_platform_interface/score) | +| [quick_actions](./packages/quick_actions/) | [![pub package](https://img.shields.io/pub/v/quick_actions.svg)](https://pub.dev/packages/quick_actions) | [![pub points](https://badges.bar/quick_actions/pub%20points)](https://pub.dev/packages/quick_actions/score) | [![popularity](https://badges.bar/quick_actions/popularity)](https://pub.dev/packages/quick_actions/score) | [![likes](https://badges.bar/quick_actions/likes)](https://pub.dev/packages/quick_actions/score) | +| [sensors](./packages/sensors/) | [![pub package](https://img.shields.io/pub/v/sensors.svg)](https://pub.dev/packages/sensors) | [![pub points](https://badges.bar/sensors/pub%20points)](https://pub.dev/packages/sensors/score) | [![popularity](https://badges.bar/sensors/popularity)](https://pub.dev/packages/sensors/score) | [![likes](https://badges.bar/sensors/likes)](https://pub.dev/packages/sensors/score) | +| [share](./packages/share/) | [![pub package](https://img.shields.io/pub/v/share.svg)](https://pub.dev/packages/share) | [![pub points](https://badges.bar/share/pub%20points)](https://pub.dev/packages/share/score) | [![popularity](https://badges.bar/share/popularity)](https://pub.dev/packages/share/score) | [![likes](https://badges.bar/share/likes)](https://pub.dev/packages/share/score) | +| [shared_preferences](./packages/shared_preferences/) | [![pub package](https://img.shields.io/pub/v/shared_preferences.svg)](https://pub.dev/packages/shared_preferences) | [![pub points](https://badges.bar/shared_preferences/pub%20points)](https://pub.dev/packages/shared_preferences/score) | [![popularity](https://badges.bar/shared_preferences/popularity)](https://pub.dev/packages/shared_preferences/score) | [![likes](https://badges.bar/shared_preferences/likes)](https://pub.dev/packages/shared_preferences/score) | +| [url_launcher](./packages/url_launcher/) | [![pub package](https://img.shields.io/pub/v/url_launcher.svg)](https://pub.dev/packages/url_launcher) | [![pub points](https://badges.bar/url_launcher/pub%20points)](https://pub.dev/packages/url_launcher/score) | [![popularity](https://badges.bar/url_launcher/popularity)](https://pub.dev/packages/url_launcher/score) | [![likes](https://badges.bar/url_launcher/likes)](https://pub.dev/packages/url_launcher/score) | +| [video_player](./packages/video_player/) | [![pub package](https://img.shields.io/pub/v/video_player.svg)](https://pub.dev/packages/video_player) | [![pub points](https://badges.bar/video_player/pub%20points)](https://pub.dev/packages/video_player/score) | [![popularity](https://badges.bar/video_player/popularity)](https://pub.dev/packages/video_player/score) | [![likes](https://badges.bar/video_player/likes)](https://pub.dev/packages/video_player/score) | +| [webview_flutter](./packages/webview_flutter/) | [![pub package](https://img.shields.io/pub/v/webview_flutter.svg)](https://pub.dev/packages/webview_flutter) | [![pub points](https://badges.bar/webview_flutter/pub%20points)](https://pub.dev/packages/webview_flutter/score) | [![popularity](https://badges.bar/webview_flutter/popularity)](https://pub.dev/packages/webview_flutter/score) | [![likes](https://badges.bar/webview_flutter/likes)](https://pub.dev/packages/webview_flutter/score) | diff --git a/analysis_options.yaml b/analysis_options.yaml index b1261f36fac9..47cdbd2f98dc 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -4,6 +4,9 @@ analyzer: # Ignore generated files - '**/*.g.dart' - 'lib/src/generated/*.dart' + errors: + always_require_non_null_named_parameters: false # not needed with nnbd + unnecessary_null_comparison: false # Turned as long as nnbd mix-mode is supported. linter: rules: - public_member_api_docs diff --git a/packages/android_alarm_manager/CHANGELOG.md b/packages/android_alarm_manager/CHANGELOG.md index faa2c731873d..df5b7a2fa752 100644 --- a/packages/android_alarm_manager/CHANGELOG.md +++ b/packages/android_alarm_manager/CHANGELOG.md @@ -1,3 +1,35 @@ +## 0.4.5+20 + +* Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets. + +## 0.4.5+19 + +* Fix outdated links across a number of markdown files ([#3276](https://github.com/flutter/plugins/pull/3276)) + +## 0.4.5+18 + +* Update Flutter SDK constraint. + +## 0.4.5+17 + +* Update Dart SDK constraint in example. + +## 0.4.5+16 + +* Remove unnecessary workaround from test. + +## 0.4.5+15 + +* Update android compileSdkVersion to 29. + +## 0.4.5+14 + +* Keep handling deprecated Android v1 classes for backward compatibility. + +## 0.4.5+13 + +* Android Code Inspection and Clean up. + ## 0.4.5+12 * Update package:e2e reference to use the local version in the flutter/plugins diff --git a/packages/android_alarm_manager/LICENSE b/packages/android_alarm_manager/LICENSE index c89293372cf3..a6d6c0749818 100644 --- a/packages/android_alarm_manager/LICENSE +++ b/packages/android_alarm_manager/LICENSE @@ -1,27 +1,25 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +Copyright 2017 The Chromium Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/packages/android_alarm_manager/README.md b/packages/android_alarm_manager/README.md index e7c7f6ee2713..cf02bf66ff11 100644 --- a/packages/android_alarm_manager/README.md +++ b/packages/android_alarm_manager/README.md @@ -1,6 +1,6 @@ # android_alarm_manager -[![pub package](https://img.shields.io/pub/v/android_alarm_manager.svg)](https://pub.dartlang.org/packages/android_alarm_manager) +[![pub package](https://img.shields.io/pub/v/android_alarm_manager.svg)](https://pub.dev/packages/android_alarm_manager) A Flutter plugin for accessing the Android AlarmManager service, and running Dart code in the background when alarms fire. @@ -36,7 +36,7 @@ Next, within the `` tags, add: android:name="io.flutter.plugins.androidalarmmanager.RebootBroadcastReceiver" android:enabled="false"> - + @@ -121,6 +121,6 @@ register plugins. This can be resolved by running `flutter upgrade` to upgrade to the latest Flutter version.** For help getting started with Flutter, view our online -[documentation](http://flutter.io/). +[documentation](https://flutter.dev/). -For help on editing plugin code, view the [documentation](https://flutter.io/platform-plugins/#edit-code). +For help on editing plugin code, view the [documentation](https://flutter.dev/docs/development/packages-and-plugins/developing-packages#plugin). diff --git a/packages/android_alarm_manager/android/build.gradle b/packages/android_alarm_manager/android/build.gradle index 04d09f62d936..5bbaf2291994 100644 --- a/packages/android_alarm_manager/android/build.gradle +++ b/packages/android_alarm_manager/android/build.gradle @@ -1,5 +1,6 @@ group 'io.flutter.plugins.androidalarmmanager' version '1.0-SNAPSHOT' +def args = ["-Xlint:deprecation","-Xlint:unchecked","-Werror"] buildscript { repositories { @@ -19,10 +20,14 @@ rootProject.allprojects { } } +project.getTasks().withType(JavaCompile){ + options.compilerArgs.addAll(args) +} + apply plugin: 'com.android.library' android { - compileSdkVersion 28 + compileSdkVersion 29 compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 diff --git a/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/AlarmService.java b/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/AlarmService.java index fb6e7f85b317..3287789f6c3d 100644 --- a/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/AlarmService.java +++ b/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/AlarmService.java @@ -13,11 +13,9 @@ import android.util.Log; import androidx.core.app.AlarmManagerCompat; import androidx.core.app.JobIntentService; -import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Set; @@ -76,9 +74,8 @@ public static void startBackgroundIsolate(Context context, long callbackHandle) synchronized (alarmQueue) { // Handle all the alarm events received before the Dart isolate was // initialized, then clear the queue. - Iterator i = alarmQueue.iterator(); - while (i.hasNext()) { - flutterBackgroundExecutor.executeDartCallbackInBackgroundIsolate(i.next(), null); + for (Intent intent : alarmQueue) { + flutterBackgroundExecutor.executeDartCallbackInBackgroundIsolate(intent, null); } alarmQueue.clear(); } @@ -93,15 +90,18 @@ public static void setCallbackDispatcher(Context context, long callbackHandle) { } /** - * Sets the {@link PluginRegistrantCallback} used to register the plugins used by an application - * with the newly spawned background isolate. + * Sets the {@link io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback} used to + * register the plugins used by an application with the newly spawned background isolate. * *

This should be invoked in {@link Application.onCreate} with {@link * GeneratedPluginRegistrant} in applications using the V1 embedding API in order to use other * plugins in the background isolate. For applications using the V2 embedding API, it is not - * necessary to set a {@link PluginRegistrantCallback} as plugins are registered automatically. + * necessary to set a {@link io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback} as + * plugins are registered automatically. */ - public static void setPluginRegistrant(PluginRegistrantCallback callback) { + @SuppressWarnings("deprecation") + public static void setPluginRegistrant( + io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback callback) { // Indirectly set in FlutterBackgroundExecutor for backwards compatibility. FlutterBackgroundExecutor.setPluginRegistrant(callback); } @@ -231,7 +231,7 @@ public static void cancel(Context context, int requestCode) { } private static String getPersistentAlarmKey(int requestCode) { - return "android_alarm_manager/persistent_alarm_" + Integer.toString(requestCode); + return "android_alarm_manager/persistent_alarm_" + requestCode; } private static void addPersistentAlarm( @@ -276,13 +276,14 @@ private static void addPersistentAlarm( } private static void clearPersistentAlarm(Context context, int requestCode) { + String request = String.valueOf(requestCode); SharedPreferences p = context.getSharedPreferences(SHARED_PREFERENCES_KEY, 0); synchronized (persistentAlarmsLock) { Set persistentAlarms = p.getStringSet(PERSISTENT_ALARMS_SET_KEY, null); - if ((persistentAlarms == null) || !persistentAlarms.contains(requestCode)) { + if ((persistentAlarms == null) || !persistentAlarms.contains(request)) { return; } - persistentAlarms.remove(requestCode); + persistentAlarms.remove(request); String key = getPersistentAlarmKey(requestCode); p.edit().remove(key).putStringSet(PERSISTENT_ALARMS_SET_KEY, persistentAlarms).apply(); @@ -301,14 +302,12 @@ public static void reschedulePersistentAlarms(Context context) { return; } - Iterator it = persistentAlarms.iterator(); - while (it.hasNext()) { - int requestCode = Integer.parseInt(it.next()); + for (String persistentAlarm : persistentAlarms) { + int requestCode = Integer.parseInt(persistentAlarm); String key = getPersistentAlarmKey(requestCode); String json = p.getString(key, null); if (json == null) { - Log.e( - TAG, "Data for alarm request code " + Integer.toString(requestCode) + " is invalid."); + Log.e(TAG, "Data for alarm request code " + requestCode + " is invalid."); continue; } try { diff --git a/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/AndroidAlarmManagerPlugin.java b/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/AndroidAlarmManagerPlugin.java index 2f3f5f9f2925..557913a626d5 100644 --- a/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/AndroidAlarmManagerPlugin.java +++ b/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/AndroidAlarmManagerPlugin.java @@ -6,6 +6,7 @@ import android.content.Context; import android.util.Log; +import io.flutter.embedding.engine.FlutterEngine; import io.flutter.embedding.engine.plugins.FlutterPlugin; import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugin.common.JSONMethodCodec; @@ -13,8 +14,6 @@ import io.flutter.plugin.common.MethodChannel; import io.flutter.plugin.common.MethodChannel.MethodCallHandler; import io.flutter.plugin.common.MethodChannel.Result; -import io.flutter.plugin.common.PluginRegistry.Registrar; -import io.flutter.view.FlutterNativeView; import org.json.JSONArray; import org.json.JSONException; @@ -28,8 +27,8 @@ *

  • The Dart side of this plugin sends the Android side a "AlarmService.start" message, along * with a Dart callback handle for a Dart callback that should be immediately invoked by a * background Dart isolate. - *
  • The Android side of this plugin spins up a background {@link FlutterNativeView}, which - * includes a background Dart isolate. + *
  • The Android side of this plugin spins up a background {@link FlutterEngine}, which includes + * a background Dart isolate. *
  • The Android side of this plugin instructs the new background Dart isolate to execute the * callback that was received in the "AlarmService.start" message. *
  • The Dart side of this plugin, running within the new background isolate, executes the @@ -49,12 +48,13 @@ public class AndroidAlarmManagerPlugin implements FlutterPlugin, MethodCallHandl /** * Registers this plugin with an associated Flutter execution context, represented by the given - * {@link Registrar}. + * {@link io.flutter.plugin.common.PluginRegistry.Registrar}. * *

    Once this method is executed, an instance of {@code AndroidAlarmManagerPlugin} will be * connected to, and running against, the associated Flutter execution context. */ - public static void registerWith(Registrar registrar) { + @SuppressWarnings("deprecation") + public static void registerWith(io.flutter.plugin.common.PluginRegistry.Registrar registrar) { if (instance == null) { instance = new AndroidAlarmManagerPlugin(); } @@ -107,37 +107,43 @@ public void onMethodCall(MethodCall call, Result result) { String method = call.method; Object arguments = call.arguments; try { - if (method.equals("AlarmService.start")) { - // This message is sent when the Dart side of this plugin is told to initialize. - long callbackHandle = ((JSONArray) arguments).getLong(0); - // In response, this (native) side of the plugin needs to spin up a background - // Dart isolate by using the given callbackHandle, and then setup a background - // method channel to communicate with the new background isolate. Once completed, - // this onMethodCall() method will receive messages from both the primary and background - // method channels. - AlarmService.setCallbackDispatcher(context, callbackHandle); - AlarmService.startBackgroundIsolate(context, callbackHandle); - result.success(true); - } else if (method.equals("Alarm.periodic")) { - // This message indicates that the Flutter app would like to schedule a periodic - // task. - PeriodicRequest periodicRequest = PeriodicRequest.fromJson((JSONArray) arguments); - AlarmService.setPeriodic(context, periodicRequest); - result.success(true); - } else if (method.equals("Alarm.oneShotAt")) { - // This message indicates that the Flutter app would like to schedule a one-time - // task. - OneShotRequest oneShotRequest = OneShotRequest.fromJson((JSONArray) arguments); - AlarmService.setOneShot(context, oneShotRequest); - result.success(true); - } else if (method.equals("Alarm.cancel")) { - // This message indicates that the Flutter app would like to cancel a previously - // scheduled task. - int requestCode = ((JSONArray) arguments).getInt(0); - AlarmService.cancel(context, requestCode); - result.success(true); - } else { - result.notImplemented(); + switch (method) { + case "AlarmService.start": + // This message is sent when the Dart side of this plugin is told to initialize. + long callbackHandle = ((JSONArray) arguments).getLong(0); + // In response, this (native) side of the plugin needs to spin up a background + // Dart isolate by using the given callbackHandle, and then setup a background + // method channel to communicate with the new background isolate. Once completed, + // this onMethodCall() method will receive messages from both the primary and background + // method channels. + AlarmService.setCallbackDispatcher(context, callbackHandle); + AlarmService.startBackgroundIsolate(context, callbackHandle); + result.success(true); + break; + case "Alarm.periodic": + // This message indicates that the Flutter app would like to schedule a periodic + // task. + PeriodicRequest periodicRequest = PeriodicRequest.fromJson((JSONArray) arguments); + AlarmService.setPeriodic(context, periodicRequest); + result.success(true); + break; + case "Alarm.oneShotAt": + // This message indicates that the Flutter app would like to schedule a one-time + // task. + OneShotRequest oneShotRequest = OneShotRequest.fromJson((JSONArray) arguments); + AlarmService.setOneShot(context, oneShotRequest); + result.success(true); + break; + case "Alarm.cancel": + // This message indicates that the Flutter app would like to cancel a previously + // scheduled task. + int requestCode = ((JSONArray) arguments).getInt(0); + AlarmService.cancel(context, requestCode); + result.success(true); + break; + default: + result.notImplemented(); + break; } } catch (JSONException e) { result.error("error", "JSON error: " + e.getMessage(), null); diff --git a/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/FlutterBackgroundExecutor.java b/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/FlutterBackgroundExecutor.java index 4e755c315528..86010ff3f089 100644 --- a/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/FlutterBackgroundExecutor.java +++ b/packages/android_alarm_manager/android/src/main/java/io/flutter/plugins/androidalarmmanager/FlutterBackgroundExecutor.java @@ -19,9 +19,7 @@ import io.flutter.plugin.common.MethodChannel; import io.flutter.plugin.common.MethodChannel.MethodCallHandler; import io.flutter.plugin.common.MethodChannel.Result; -import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback; import io.flutter.view.FlutterCallbackInformation; -import io.flutter.view.FlutterMain; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicBoolean; @@ -32,7 +30,10 @@ public class FlutterBackgroundExecutor implements MethodCallHandler { private static final String TAG = "FlutterBackgroundExecutor"; private static final String CALLBACK_HANDLE_KEY = "callback_handle"; - private static PluginRegistrantCallback pluginRegistrantCallback; + + @SuppressWarnings("deprecation") + private static io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback + pluginRegistrantCallback; /** * The {@link MethodChannel} that connects the Android side of this plugin with the background @@ -45,14 +46,16 @@ public class FlutterBackgroundExecutor implements MethodCallHandler { private AtomicBoolean isCallbackDispatcherReady = new AtomicBoolean(false); /** - * Sets the {@code PluginRegistrantCallback} used to register plugins with the newly spawned - * isolate. + * Sets the {@code io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback} used to + * register plugins with the newly spawned isolate. * *

    Note: this is only necessary for applications using the V1 engine embedding API as plugins * are automatically registered via reflection in the V2 engine embedding API. If not set, alarm * callbacks will not be able to utilize functionality from other plugins. */ - public static void setPluginRegistrant(PluginRegistrantCallback callback) { + @SuppressWarnings("deprecation") + public static void setPluginRegistrant( + io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback callback) { pluginRegistrantCallback = callback; } @@ -78,7 +81,6 @@ private void onInitialized() { @Override public void onMethodCall(MethodCall call, Result result) { String method = call.method; - Object arguments = call.arguments; try { if (method.equals("AlarmService.initialized")) { // This message is sent by the background method channel as soon as the background isolate @@ -102,7 +104,7 @@ public void onMethodCall(MethodCall call, Result result) { *

    The isolate is configured as follows: * *