diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..ad4bc5444 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,35 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +indent_style = space +indent_size = 4 + +[*.{kt,kts}] +indent_size = 4 +max_line_length = 100 +ij_kotlin_allow_trailing_comma = true +ij_kotlin_allow_trailing_comma_on_call_site = true +ij_kotlin_packages_to_use_import_on_demand = unset + +[*.java] +indent_size = 4 +max_line_length = 100 + +[*.{xml,gradle}] +indent_size = 4 + +[*.{yml,yaml,json}] +indent_size = 2 + +[*.md] +trim_trailing_whitespace = false + +[*.{bat,cmd}] +end_of_line = crlf + +[Makefile] +indent_style = tab diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8ae5dc370..0f7fe1095 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -25,6 +25,9 @@ on: types: [ build ] workflow_dispatch: +permissions: + contents: read + # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: build-ApiDemos: @@ -32,16 +35,18 @@ jobs: timeout-minutes: 45 steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: set up Java 21 - uses: actions/setup-java@v5 + uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5.7.0 with: distribution: 'temurin' java-version: '21' - name: Setup Gradle - uses: gradle/actions/setup-gradle@v6 + uses: gradle/actions/setup-gradle@9c971963bec38e04b3d30dcc455b5382be2fdbfb # v6.3.0 - name: Build and check run: | @@ -55,16 +60,18 @@ jobs: timeout-minutes: 45 steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: set up Java 21 - uses: actions/setup-java@v5 + uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5.7.0 with: distribution: 'temurin' java-version: '21' - name: Setup Gradle - uses: gradle/actions/setup-gradle@v6 + uses: gradle/actions/setup-gradle@9c971963bec38e04b3d30dcc455b5382be2fdbfb # v6.3.0 - name: Build and check run: ./gradlew :WearOS:Wearable:assembleDebug @@ -74,16 +81,18 @@ jobs: timeout-minutes: 45 steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: set up Java 21 - uses: actions/setup-java@v5 + uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5.7.0 with: distribution: 'temurin' java-version: '21' - name: Setup Gradle - uses: gradle/actions/setup-gradle@v6 + uses: gradle/actions/setup-gradle@9c971963bec38e04b3d30dcc455b5382be2fdbfb # v6.3.0 - name: Build and check run: ./gradlew :FireMarkers:app:assembleDebug @@ -93,16 +102,18 @@ jobs: timeout-minutes: 45 steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: set up Java 21 - uses: actions/setup-java@v5 + uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5.7.0 with: distribution: 'temurin' java-version: '21' - name: Setup Gradle - uses: gradle/actions/setup-gradle@v6 + uses: gradle/actions/setup-gradle@9c971963bec38e04b3d30dcc455b5382be2fdbfb # v6.3.0 - name: Build and check run: | @@ -118,16 +129,18 @@ jobs: timeout-minutes: 45 steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: set up Java 21 - uses: actions/setup-java@v5 + uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5.7.0 with: distribution: 'temurin' java-version: '21' - name: Setup Gradle - uses: gradle/actions/setup-gradle@v6 + uses: gradle/actions/setup-gradle@9c971963bec38e04b3d30dcc455b5382be2fdbfb # v6.3.0 - name: Build and check run: | @@ -143,9 +156,11 @@ jobs: - build-Snippets - build-tutorials steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: set up Java 21 - uses: actions/setup-java@v5 + uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5.7.0 with: distribution: 'temurin' java-version: '21' diff --git a/.github/workflows/generate-v3.yml b/.github/workflows/generate-v3.yml deleted file mode 100644 index 3a25059db..000000000 --- a/.github/workflows/generate-v3.yml +++ /dev/null @@ -1,65 +0,0 @@ -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: Generate V3 Samples - -on: - workflow_dispatch: - repository_dispatch: - types: [ generate-v3 ] - -jobs: - generate-v3: - runs-on: ubuntu-latest - timeout-minutes: 45 - - steps: - - uses: actions/checkout@v6 - - - name: set up JDK 17 - uses: actions/setup-java@v5 - with: - distribution: 'temurin' - java-version: 17 - - - name: Setup Gradle - uses: gradle/actions/setup-gradle@v6 - - - name: Install NDK - run: | - sudo ${ANDROID_HOME}/cmdline-tools/latest/bin/sdkmanager --install "ndk;20.0.5594570" - - - name: Generate V3 - id: gradlew-generate-v3 - run: | - ./gradlew :ApiDemos:java-app:generateV3 :ApiDemos:java-app:generateV3Layout - ./gradlew :ApiDemos:kotlin-app:generateV3 :ApiDemos:kotlin-app:generateV3Layout - echo "files-changed=$(git status -s | wc -l)" >> $GITHUB_OUTPUT - - - name: PR Changes - uses: peter-evans/create-pull-request@v8 - if: steps.gradlew-generate-v3.outputs.files-changed > 0 - with: - token: ${{ secrets.SYNCED_GITHUB_TOKEN_REPO }} - commit-message: 'chore: Generate V3 samples' - committer: googlemaps-bot - author: googlemaps-bot - title: 'chore: Generate V3 samples' - body: | - Generating V3 code via `./gradlew generateV3 generateV3Layout` - branch: googlemaps-bot/generate-v3 - - - name: Uninstall NDK - run: | - ${ANDROID_HOME}/cmdline-tools/latest/bin/sdkmanager --uninstall 'ndk;20.0.5594570' diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 2fc362379..930a11e7c 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -19,22 +19,28 @@ on: branches: - main +permissions: + contents: read + security-events: write + jobs: lint: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v6 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: Set up JDK 17 - uses: actions/setup-java@v5 + uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5.7.0 with: distribution: 'temurin' java-version: '21' - name: Set up Python - uses: actions/setup-python@v6 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: '3.x' @@ -42,7 +48,7 @@ jobs: run: python3 scripts/update_docs_versions.py --check - name: Setup Gradle - uses: gradle/actions/setup-gradle@v6 + uses: gradle/actions/setup-gradle@9c971963bec38e04b3d30dcc455b5382be2fdbfb # v6.3.0 - name: Run Android Lint run: | @@ -59,67 +65,67 @@ jobs: ./gradlew :FireMarkers:app:lintDebug - name: Upload SARIF for ApiDemos:kotlin-app - uses: github/codeql-action/upload-sarif@v4 + uses: github/codeql-action/upload-sarif@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7 with: sarif_file: ApiDemos/project/kotlin-app/build/reports/lint-results-debug.sarif category: ApiDemos-kotlin-app - name: Upload SARIF for ApiDemos:java-app - uses: github/codeql-action/upload-sarif@v4 + uses: github/codeql-action/upload-sarif@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7 with: sarif_file: ApiDemos/project/java-app/build/reports/lint-results-debug.sarif category: ApiDemos-java-app - name: Upload SARIF for ApiDemos:common-ui - uses: github/codeql-action/upload-sarif@v4 + uses: github/codeql-action/upload-sarif@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7 with: sarif_file: ApiDemos/project/common-ui/build/reports/lint-results-debug.sarif category: ApiDemos-common-ui - name: Upload SARIF for snippets:app - uses: github/codeql-action/upload-sarif@v4 + uses: github/codeql-action/upload-sarif@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7 with: sarif_file: snippets/app/build/reports/lint-results-debug.sarif category: snippets-app - name: Upload SARIF for snippets:app-utils - uses: github/codeql-action/upload-sarif@v4 + uses: github/codeql-action/upload-sarif@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7 with: sarif_file: snippets/app-utils/build/reports/lint-results-debug.sarif category: snippets-app-utils - name: Upload SARIF for snippets:app-utils-ktx - uses: github/codeql-action/upload-sarif@v4 + uses: github/codeql-action/upload-sarif@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7 with: sarif_file: snippets/app-utils-ktx/build/reports/lint-results-debug.sarif category: snippets-app-utils-ktx - name: Upload SARIF for snippets:app-places-ktx - uses: github/codeql-action/upload-sarif@v4 + uses: github/codeql-action/upload-sarif@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7 with: sarif_file: snippets/app-places-ktx/build/reports/lint-results-debug.sarif category: snippets-app-places-ktx - name: Upload SARIF for snippets:app-ktx - uses: github/codeql-action/upload-sarif@v4 + uses: github/codeql-action/upload-sarif@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7 with: sarif_file: snippets/app-ktx/build/reports/lint-results-debug.sarif category: snippets-app-ktx - name: Upload SARIF for snippets:app-compose - uses: github/codeql-action/upload-sarif@v4 + uses: github/codeql-action/upload-sarif@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7 with: sarif_file: snippets/app-compose/build/reports/lint-results-debug.sarif category: snippets-app-compose - name: Upload SARIF for WearOS:Wearable - uses: github/codeql-action/upload-sarif@v4 + uses: github/codeql-action/upload-sarif@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7 with: sarif_file: WearOS/Wearable/build/reports/lint-results-debug.sarif category: WearOS-Wearable - name: Upload SARIF for FireMarkers:app - uses: github/codeql-action/upload-sarif@v4 + uses: github/codeql-action/upload-sarif@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7 with: sarif_file: FireMarkers/app/build/reports/lint-results-debug.sarif category: FireMarkers-app \ No newline at end of file diff --git a/.gitignore b/.gitignore index 275449d61..80934aa5c 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,5 @@ secrets.properties # This covers new IDEs, like Antigravity .vscode/ -**/bin/ \ No newline at end of file +**/bin/ +.kotlin/ \ No newline at end of file diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 9efb74312..20e9dbd7c 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "2.0.2" + ".": "2.1.0" } \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 000000000..b936d92dd --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,78 @@ +# AGENTS.md + +Guidance for AI coding agents working on this repository. For human contribution +rules (CLA, PR process, AI-assisted contribution policy), see [CONTRIBUTING.md](CONTRIBUTING.md). + +## Project overview + +Sample code for the Maps SDK for Android. This is a multi-app repository: + +| Area | Purpose | +| --- | --- | +| `ApiDemos` | Feature demos in parallel `java-app` and `kotlin-app` variants plus `common-ui` | +| `snippets` | Code excerpts published into the official documentation (`app`, `app-ktx`, `app-utils`, `app-utils-ktx`, `app-compose`, `app-places-ktx`) | +| `tutorials` | Standalone mini-projects backing written tutorials, in `java/` and `kotlin/` | +| `FireMarkers` | Firebase + Maps sample app | +| `WearOS` | Wear OS sample app | + +## Region tags feed official documentation + +Code excerpts in `snippets/`, as well as key sample activities in `ApiDemos` and +root build files, are extracted into developers.google.com pages via +region tag comment markers (paired START and END lines wrapping each excerpt). + +- Never rename, remove, or reorder region tags, and keep every START/END pair + balanced. +- Do not reformat or "clean up" code inside a tagged region unless the change + is the point of the PR; the published docs mirror it verbatim. +- Java and Kotlin snippet modules (`app` vs `app-ktx`) document the same + features; a change to one usually needs the equivalent change in the other. + +The same parity rule applies to `ApiDemos`: `java-app` and `kotlin-app` +demonstrate the same features and must stay in sync. + +## Code style and hygiene + +- Adhere to formatting rules defined in `.editorconfig`. +- Do not use wildcard imports (`import foo.*`); use explicit imports. +- Avoid fully qualified class names in source code; declare explicit imports at the file level instead (except to resolve naming collisions or in XML layouts). + +## Building and testing + +- **Full project verification:** + ```bash + ./scripts/verify_all.sh # run assemble, unit tests, lint, and doc version checks across all root modules + ``` + +- **Targeted module builds:** + ```bash + ./gradlew :ApiDemos:kotlin-app:assembleDebug # build a specific demo app + ./gradlew :snippets:app-ktx:assembleDebug # compile a specific snippet module + ``` + +- **Documentation version check:** + ```bash + python3 scripts/update_docs_versions.py --check # verify doc snippet versions match version catalog + ``` + +Snippet modules do not contain unit tests; they are verified through successful compilation (`assembleDebug`), Android lint (`lintDebug`), and doc version synchronization. + +Running the apps requires a Maps API key: copy the keys named in +`local.defaults.properties` (e.g. `MAPS_API_KEY`) into `local.properties`. +The secrets-gradle-plugin injects them at build time. Never hardcode or +commit API keys. + +Note that most `tutorials/` projects are standalone Gradle builds not wired +into the root `settings.gradle.kts`; build them from their own directory. + +## Pull requests + +- Use Conventional Commit messages (`feat:`, `fix:`, `docs:`, ...). + release-please parses them to generate versions and CHANGELOG.md; a wrong + prefix causes a wrong release bump. Never edit CHANGELOG.md by hand. +- Keep changes scoped to one sample or one feature across its language + variants; do not mix unrelated samples in one PR. +- Build and test the affected modules before declaring work done, and report actual + results. +- AI tools must not be listed as authors or co-authors on commits or PRs, and + unsolicited bot-generated PRs are prohibited (see CONTRIBUTING.md). diff --git a/ApiDemos/V3_FILE_HEADER b/ApiDemos/V3_FILE_HEADER deleted file mode 100644 index 603294c26..000000000 --- a/ApiDemos/V3_FILE_HEADER +++ /dev/null @@ -1,7 +0,0 @@ -/** - * DO NOT EDIT THIS FILE. - * - * This source code was autogenerated from source code within the `app/src/gms` directory - * and is not intended for modifications. If any edits should be made, please do so in the - * corresponding file under the `app/src/gms` directory. - */ diff --git a/ApiDemos/project/README.md b/ApiDemos/project/README.md index aedd55535..90cf6ac66 100644 --- a/ApiDemos/project/README.md +++ b/ApiDemos/project/README.md @@ -5,10 +5,8 @@ These are demos for the [Maps SDK for Android](https://developers.google.com/map They demonstrate most of the features available in the API. -The Maps SDK for Android samples can be found under the `main` gradle product -flavor, while the Maps SDK V3 BETA samples can be found under the `v3` gradle -product flavor. The active product flavor can be modified through -Android Studio’s “Build Variants” toolbar options. +The samples are organized into parallel `java-app` and `kotlin-app` modules +sharing UI components via `common-ui`. Pre-requisites -------------- diff --git a/ApiDemos/project/common-ui/build.gradle.kts b/ApiDemos/project/common-ui/build.gradle.kts index dfcd8352b..595680348 100644 --- a/ApiDemos/project/common-ui/build.gradle.kts +++ b/ApiDemos/project/common-ui/build.gradle.kts @@ -18,7 +18,6 @@ import org.jetbrains.kotlin.gradle.dsl.JvmTarget plugins { alias(libs.plugins.android.library) - alias(libs.plugins.kotlin.android) } android { diff --git a/ApiDemos/project/java-app/src/v3/res/layout/marker_collision_demo.xml b/ApiDemos/project/common-ui/src/main/res/drawable/bg_marker_badge.xml similarity index 64% rename from ApiDemos/project/java-app/src/v3/res/layout/marker_collision_demo.xml rename to ApiDemos/project/common-ui/src/main/res/drawable/bg_marker_badge.xml index d587601db..3b413cf19 100644 --- a/ApiDemos/project/java-app/src/v3/res/layout/marker_collision_demo.xml +++ b/ApiDemos/project/common-ui/src/main/res/drawable/bg_marker_badge.xml @@ -1,6 +1,6 @@ - + + + + + diff --git a/ApiDemos/project/common-ui/src/main/res/drawable/ic_camera.xml b/ApiDemos/project/common-ui/src/main/res/drawable/ic_camera.xml new file mode 100644 index 000000000..a16c5e068 --- /dev/null +++ b/ApiDemos/project/common-ui/src/main/res/drawable/ic_camera.xml @@ -0,0 +1,28 @@ + + + + + diff --git a/ApiDemos/project/common-ui/src/main/res/drawable/ic_clear.xml b/ApiDemos/project/common-ui/src/main/res/drawable/ic_clear.xml new file mode 100644 index 000000000..a7280e26d --- /dev/null +++ b/ApiDemos/project/common-ui/src/main/res/drawable/ic_clear.xml @@ -0,0 +1,25 @@ + + + + diff --git a/ApiDemos/project/common-ui/src/main/res/drawable/ic_my_location.xml b/ApiDemos/project/common-ui/src/main/res/drawable/ic_my_location.xml new file mode 100644 index 000000000..ec26c8b2b --- /dev/null +++ b/ApiDemos/project/common-ui/src/main/res/drawable/ic_my_location.xml @@ -0,0 +1,25 @@ + + + + diff --git a/ApiDemos/project/java-app/src/v3/res/layout/map_in_pager_demo.xml b/ApiDemos/project/common-ui/src/main/res/drawable/ic_view_grid.xml old mode 100755 new mode 100644 similarity index 56% rename from ApiDemos/project/java-app/src/v3/res/layout/map_in_pager_demo.xml rename to ApiDemos/project/common-ui/src/main/res/drawable/ic_view_grid.xml index 931cb73ea..b7f6ad231 --- a/ApiDemos/project/java-app/src/v3/res/layout/map_in_pager_demo.xml +++ b/ApiDemos/project/common-ui/src/main/res/drawable/ic_view_grid.xml @@ -1,6 +1,5 @@ - - + + + diff --git a/ApiDemos/project/java-app/src/v3/res/layout/legal_info.xml b/ApiDemos/project/common-ui/src/main/res/drawable/ic_view_list.xml old mode 100755 new mode 100644 similarity index 57% rename from ApiDemos/project/java-app/src/v3/res/layout/legal_info.xml rename to ApiDemos/project/common-ui/src/main/res/drawable/ic_view_list.xml index 2d8079887..c93fbc29d --- a/ApiDemos/project/java-app/src/v3/res/layout/legal_info.xml +++ b/ApiDemos/project/common-ui/src/main/res/drawable/ic_view_list.xml @@ -1,6 +1,5 @@ - - - - - + + + diff --git a/ApiDemos/project/common-ui/src/main/res/layout-land/snapshot_demo.xml b/ApiDemos/project/common-ui/src/main/res/layout-land/snapshot_demo.xml index 3f59eb7ee..1dce43bf5 100755 --- a/ApiDemos/project/common-ui/src/main/res/layout-land/snapshot_demo.xml +++ b/ApiDemos/project/common-ui/src/main/res/layout-land/snapshot_demo.xml @@ -1,6 +1,6 @@ - + android:layout_height="match_parent"> + + + android:layout_marginHorizontal="16dp" + android:layout_marginTop="8dp" + android:layout_marginBottom="4dp" + android:orientation="horizontal" + app:layout_constraintTop_toBottomOf="@id/topAppBar" + app:layout_constraintBottom_toTopOf="@id/bottom_controls" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toEndOf="parent"> - + + android:layout_weight="1" + android:layout_marginEnd="6dp" + app:cardCornerRadius="16dp" + app:cardElevation="2dp" + app:strokeWidth="1dp" + app:strokeColor="?attr/colorOutlineVariant"> + + + + - + + + + + + android:layout_weight="1" + android:layout_marginStart="6dp" + app:cardCornerRadius="16dp" + app:cardElevation="2dp" + app:strokeWidth="1dp" + app:strokeColor="?attr/colorOutlineVariant"> + + + + + + + + + + + - + android:layout_marginHorizontal="16dp" + android:layout_marginBottom="8dp" + android:orientation="horizontal" + android:gravity="center_vertical" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toEndOf="parent"> - + -