Skip to content

fix(bluetoothle): fix typo in BluetoothLeService and migrate to snippets#934

Draft
ithinkihaveacat wants to merge 22 commits into
android:mainfrom
ithinkihaveacat:fix-359501045
Draft

fix(bluetoothle): fix typo in BluetoothLeService and migrate to snippets#934
ithinkihaveacat wants to merge 22 commits into
android:mainfrom
ithinkihaveacat:fix-359501045

Conversation

@ithinkihaveacat

Copy link
Copy Markdown
Contributor
  • Fix typo 'Return;' -> 'return;' in Java BluetoothLeService.
  • Migrate inline code samples from connect-gatt-server.md to snippets.
  • Create BluetoothLeService and DeviceControlActivity in Java and Kotlin.
  • Add gatt_services_characteristics layout and string resources to enable compilation.

Bug: 359501045

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces Bluetooth Low Energy (BLE) GATT service and activity implementations in both Java and Kotlin. The code reviewer identified several critical issues, including potential GATT connection leaks due to unclosed BluetoothGatt instances, ServiceConnection leaks from missing unbindService calls in onDestroy, control flow bugs where connection attempts proceed after initialization failures, and unsafe null assertions (!!) in the Kotlin activity that could cause runtime crashes.

Comment on lines +89 to +97
if (!bluetoothService.initialize()) {
Log.e(TAG, "Unable to initialize Bluetooth");
finish();
}
// [END gatt_initialize_activity_java]
// perform device connection
// [START gatt_connect_activity_java]
bluetoothService.connect(deviceAddress);
// [END gatt_connect_activity_java]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

If bluetoothService.initialize() fails, finish() is called to destroy the activity, but the method continues executing and attempts to call connect(). Add an early return; statement to prevent further execution.

                if (!bluetoothService.initialize()) {\n                    Log.e(TAG, "Unable to initialize Bluetooth");\n                    finish();\n                    return;\n                }\n                // [END gatt_initialize_activity_java]\n                // perform device connection\n                // [START gatt_connect_activity_java]\n                bluetoothService.connect(deviceAddress);\n                // [END gatt_connect_activity_java]

@ithinkihaveacat ithinkihaveacat force-pushed the fix-359501045 branch 2 times, most recently from c7852e3 to a02d6a9 Compare June 1, 2026 16:06
@ithinkihaveacat ithinkihaveacat marked this pull request as ready for review June 1, 2026 16:30
@snippet-bot

snippet-bot Bot commented Jun 1, 2026

Copy link
Copy Markdown

Here is the summary of changes.

You are about to add 34 region tags.

This comment is generated by snippet-bot.
If you find problems with this result, please file an issue at:
https://github.com/googleapis/repo-automation-bots/issues.
To update this comment, add snippet-bot:force-run label or use the checkbox below:

  • Refresh this comment

@ithinkihaveacat

Copy link
Copy Markdown
Contributor Author

These snippets have been ported directly from https://developer.android.com/develop/connectivity/bluetooth/ble/connect-gatt-server using a tool I'm testing.

The comments from gemini-code-assist seem mostly reasonable however I am not a SME and so I'd rather not make any changes if possible.

@ithinkihaveacat ithinkihaveacat force-pushed the fix-359501045 branch 2 times, most recently from fc4336f to 439afc5 Compare June 1, 2026 16:44
- Fix typo 'Return;' -> 'return;' in Java BluetoothLeService.
- Migrate inline code samples from connect-gatt-server.md to snippets.
- Create BluetoothLeService and DeviceControlActivity in Java and Kotlin.
- Add gatt_services_characteristics layout and string resources to enable compilation.

Bug: 359501045
@ithinkihaveacat ithinkihaveacat enabled auto-merge (squash) June 1, 2026 21:32
@kkuan2011

Copy link
Copy Markdown
Contributor

Thanks Michael! Would you mind getting a Bluetooth SME to approve first? Then Yacine/I can approve to merge.

@ithinkihaveacat

Copy link
Copy Markdown
Contributor Author

Hey @kkuan2011

Thanks Michael! Would you mind getting a Bluetooth SME to approve first? Then Yacine/I can approve to merge.

I checked with our Bluetooth SME and made a small change (0007881).

@kkuan2011 kkuan2011 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I do a side by side visual comparison with the original page, I see the snippets have changed
https://developer.android.com/develop/connectivity/bluetooth/ble/connect-gatt-server

They omit the Service declaration that wraps a lot of the original snippets, function names have changed (which I understand was to avoid name conflicts within the same file), some global variables also got dropped, annotations got added. Is that what you were expecting?

I do try handling some of these cases in my snippet skill so you may want to try migrating the page with that, or fixing each difference in your current CL by iterating with the agent. It's a tedious process though.. i know :/

…nection snippets

- Implemented 'Silent Wrapper' technique to resolve name inconsistencies (simpleConnect -> connect, simpleBluetoothGattCallback -> bluetoothGattCallback, simpleServiceConnection -> serviceConnection) without breaking compilation.
- Moved @RequiresPermission annotations outside of snippet region tags or wrapped them in silent excludes to match original documentation.
- Renamed 'Dummy implementation' to 'Placeholder implementation'.
- Removed temporary 'FIXED' comment in BluetoothLeService.java.
- Cleaned up duplicate region tags in BluetoothLeService.kt.
Extend update receiver regions in DeviceControlActivity (Java/Kotlin) to cover lifecycle methods, using silent excludes to hide onCreate and permission annotations. This matches the DAC documentation page structure exactly while keeping the repository code compilable.
Migrate the entire BluetoothLeService binder code block (including
class declaration) into the repository as a new region tag
'android_bluetooth_service_binder'.

Use silent exclusions to hide the rest of the class methods,
ensuring the snippet is 100% generated from the source file
without hardcoding wrappers in the markdown.
Revert the risky nested exclusions in the main BluetoothLeService
files. Instead, split the binder-only snippet into dedicated
files in a separate 'binder' package (to avoid name clashes).

This ensures the binder snippet is cleanly imported with its class
wrapper, without using dangerous nested exclusions, and keeping
all code 100% in the repository.
Remove the old 'android_bluetooth_binder' and
'android_bluetooth_binder_java' region tags from the main
BluetoothLeService files, as they have been replaced by the new
dedicated binder snippets.
Remove 'android_bluetooth_receiver_lifecycle' and
'android_bluetooth_receiver_lifecycle_java' tags from
DeviceControlActivity files.

These sub-regions are now redundant because they are fully
merged into the parent 'android_bluetooth_update_receiver'
regions to fix the snippet length issue.
Add the 'android_bluetooth_connect_gatt' (and Java) tags around the
connectGatt call in BluetoothLeService to allow importing it
without class wrappers.

Expand the 'android_bluetooth_bind_service' (and Java) tags to
cover the entire onCreate method, enabling clean imports in the
documentation.
Now that we have simplified the documentation to remove all
hardcoded class wrappers, the binder snippet also no longer
needs the class wrapper.

Thus, we can revert the split and move the binder snippet tags
back to the main BluetoothLeService files, deleting the
redundant 'binder' package files.
@ithinkihaveacat

Copy link
Copy Markdown
Contributor Author

When I do a side by side visual comparison with the original page, I see the snippets have changed https://developer.android.com/develop/connectivity/bluetooth/ble/connect-gatt-server

[...]

Is that what you were expecting?

No, and I apologize for missing this, and the other issues you pointed out!

These should now be resolved, although it's quite difficult for anyone to review without the context of a rendered DAC page that incorporates the snippets.

Note: as part of the most recent changes I removed the outer class wrappers from these snippets to keep the repo clean. Because the page shows progressive steps of the same class (like initialize, connect, and close), preserving the wrappers in a single file results in conflicting tag exclusions. I think this is the right way to go: keeping them would have forced us to split the code into 5-6 duplicate files in the repo (one per snippet).

Merge consecutive region tags into single combined tags to simplify
the documentation imports and remove redundant splits:

1. Merge 'service_connection' and 'bind_service' in
   DeviceControlActivity by reordering onCreate to be immediately
   after serviceConnection.
2. Merge 'callback' and 'constants' in BluetoothLeService by
   reordering the companion object and callback to the top of the
   class.

Also fix the silent wrapper tagging in BluetoothLeService callback
to ensure the declaration and its closing brace are rendered.
Apply spotless formatting fix to BluetoothLeService.kt.

@kkuan2011 kkuan2011 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't done a full review yet, but since it looks like what will be shown in the resulting DAC page will look different, could you run it by a bluetooth SME one more time? It may be easier to generate a diff report of what is different, so it's easier to see + confirm if those changes are ok. Thank you Michael!

@ithinkihaveacat ithinkihaveacat marked this pull request as draft June 8, 2026 13:26
auto-merge was automatically disabled June 8, 2026 13:26

Pull request was converted to draft

Remove unused Java snippet files and update Kotlin snippets to use
silent wrappers and correct region tags to match DevSite structure.
@ithinkihaveacat

Copy link
Copy Markdown
Contributor Author

Ok, flipping this PR back to ready for review. Thanks for the comments!

Here's a summary of the PR and the rationale for the (small!) differences between the repository code and the original hardcoded documentation.

1. Bug Fixes, Safety & Correctness

  • Null Safety: Replaced unsafe null assertions (!!) with safe calls (?.let) in DeviceControlActivity.kt to prevent runtime crashes.
  • Typo Fix: Corrected a typo in DeviceControlActivity.kt where it referenced a non-existent plural activity class (DeviceControlsActivity.TAG) for the log TAG.
  • Control Flow Fix: Added a missing return statement in BluetoothLeServiceSimple.kt's connect function to ensure correct compilation.
  • Lint Compliance: Resolved a MissingPermission lint failure on gatt.close() by applying a class-level @SuppressLint("MissingPermission") in BluetoothLeService.kt. The annotation is placed outside the region tags to keep it hidden from the rendered documentation.
  • Java Snippets: Removed the Java implementation entirely (per previous review agreement) to align with Android's Kotlin-first direction and reduce maintenance overhead.

2. Structural Changes & Render Differences

To prioritize repository maintainability and avoid duplicating entire Service/Activity files 5-6 times, we consolidated progressive steps of the same class into single helper files (DeviceControlActivitySimple.kt, BluetoothLeServiceSimple.kt). This results in some minor, intentional differences in the rendered documentation:

  • Contextual Comments: Since outer class wrappers were removed to keep the repository clean, we added explicit comments (e.g., // In DeviceControlActivity) at the top of the snippets to preserve necessary context for the reader.
  • Boilerplate Reduction: Some snippets now focus purely on the functional API calls (e.g., the connect function) rather than the surrounding class boilerplate, making them cleaner and more focused.
  • Collision Resolution: Naming collisions in helper files were resolved using private inner classes, which are silently excluded from the rendered output using DevSite tags to keep the documentation clean.
  • Layout Refinement: In some cases, we reordered elements (like consolidating the companion object and callback) to present a more contiguous and readable flow on the page.

3. Rendered Preview

The changes have been verified using an internal staging system. The rendered output matches the original documentation layout while incorporating the safety, correctness, and context improvements noted above. (Details shared separately).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants