-
Notifications
You must be signed in to change notification settings - Fork 350
Add Android backend using Chaquopy/Briefcase #1944
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
timrid
wants to merge
45
commits into
hbldh:develop
Choose a base branch
from
timrid:android-backend-using-chaquopy
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 26 commits
Commits
Show all changes
45 commits
Select commit
Hold shift + click to select a range
ef72121
backend: Add new Android backend for usage with Chaquopy / briefcase
timrid 108936f
docs: Remove reference to python for android from android backend
timrid b0cc712
docs: Fixed typo
timrid 47c29e9
docs: change .md to .rst
timrid f78ae29
tests: fixed typo
timrid d06c576
android: Add missing check
timrid c07b7fd
android: flushPendingScanResults is not required
timrid 163cf5e
android: Add missing permission check, when not using a Scanner
timrid c9cebb3
android: ParamSpec is available since python 3.10
timrid a7b4277
android: Refactor error handling in dispatcher by logging it only and…
timrid fb08ad8
android: Dont use deprecated api on onDescriptorRead and API Level 33…
timrid 690ff29
android: Fix mtu variable
timrid c77ba1d
android: Update writeCharacteristic and writeDescriptor handling for …
timrid d02d8c0
android: Add None check for `getBluetoothLeScanner()`.
timrid 947ee57
android: cleanup future after it is awaited
timrid 1159757
android: Dont request ACCESS_BACKGROUND_LOCATION permission by defaul…
timrid 17f1674
android: Improve error handling in `start_notify()`
timrid 2f93c31
android: Check gatt explicitly
timrid e81c940
android: Notifications and indications should not be used together.
timrid 4b87b46
android: Handle scanner state reset on startScan failure
timrid f86e17c
android: Make Android CI work again, by using skinless emulator.
timrid ca3520d
android: Update Toga dependencies to specific commit for stability
timrid 389c7f2
android: Ignore notifications for unsubscribed handles in Bluetooth G…
timrid b52bb29
android: Add an early serial port check to prevent to long waiting ti…
timrid 8d8b115
android: Improve permission denial exception message.
timrid e5d5d99
docs: Update android docs to clarify Python version requirement and B…
timrid 7e39ba3
android: Disable snapshots for emulator to ensure a clean start in in…
timrid dd0f21a
android: remove unnecessary try-except blocks
timrid 9a1ffe5
docs: Wrap after approx 80 characters
timrid d106ca3
docs: renamed android-beeware.rst to android.rst
timrid 0a8e262
docs: update warning message
timrid 987aeeb
docs: clarify reason for skipping pairing tests on Android backend
timrid edf337a
android: update mypy android config to 3.13
timrid 177a0ff
docs: fix toc after file rename
timrid fa9e237
ci: run integration tests on android api level 31 and 33
timrid 4a5e56e
ci: fix pyright error that was introduces with pyright v1.1.409
timrid 92a7849
ci: update KVM permissions comment for Android emulator setup
timrid 9488372
Merge commit '058c4e274c58e99d1d3dfdd87f7d8f1bd0fb2321' into android-…
timrid 6d63bb5
tests: fix issue 1885 test on Android
timrid bc8b83a
android: simplify dispatcher
timrid baefc3b
android: remove unnecessary type conversion
timrid 6864668
tests: remove unnecessary testbed files
timrid f3ee7e5
tests: add comment what the testbed does
timrid e0b0c86
tests: add support for duplicate service, characteristic and descript…
timrid b0506c8
android: log service, characteristic, and descriptor uuid, instanceId…
timrid File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -51,6 +51,7 @@ nosetests.xml | |
| coverage.xml | ||
| *,cover | ||
| .hypothesis/ | ||
| junit.xml | ||
|
|
||
| # Integration test VM | ||
| .alpine-vm-build/ | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| from __future__ import annotations | ||
|
|
||
| import sys | ||
| from typing import TYPE_CHECKING | ||
|
|
||
| if TYPE_CHECKING: | ||
| if sys.platform != "android": | ||
| assert False, "This backend is only available on Android" | ||
|
|
||
| import logging | ||
| from typing import Callable | ||
|
|
||
| from android.content import BroadcastReceiver as _BroadcastReceiver | ||
| from android.content import Context, Intent, IntentFilter | ||
| from android.os import Handler, HandlerThread | ||
| from java import Override, jvoid, static_proxy | ||
|
|
||
| from bleak.backends._utils import external_thread_callback | ||
| from bleak.backends.android.utils import context | ||
|
|
||
| logger = logging.getLogger(__name__) | ||
|
|
||
|
|
||
| # Copied BroadcastReceiver logic from python-for-android and adapted it to chaquopy. | ||
| # See https://github.com/kivy/python-for-android/blob/6f3ab805972e0d9531e3a207a6bc51c0effd8eb9/pythonforandroid/recipes/android/src/android/broadcast.py | ||
| class BroadcastReceiver(static_proxy(_BroadcastReceiver)): # type: ignore[misc] | ||
| def __init__( | ||
| self, | ||
| callback: Callable[[Context, Intent], None], | ||
| actions: list[str] | None = None, | ||
| categories: list[str] | None = None, | ||
| ): | ||
| super(BroadcastReceiver, self).__init__() | ||
| self.context = context | ||
| self.callback = callback | ||
|
|
||
| if not actions and not categories: | ||
| raise Exception("You need to define at least actions or categories") | ||
|
|
||
| def _expand_partial_name(partial_name: str): | ||
| if "." in partial_name: | ||
| return partial_name # Its actually a full dotted name | ||
| else: | ||
| name = "ACTION_{}".format(partial_name.upper()) | ||
| if not hasattr(Intent, name): | ||
| raise Exception("The intent {} does not exist".format(name)) | ||
| return getattr(Intent, name) | ||
|
|
||
| # resolve actions/categories first | ||
| resolved_actions = [_expand_partial_name(x) for x in actions or []] | ||
| resolved_categories = [_expand_partial_name(x) for x in categories or []] | ||
|
|
||
| # create a thread for handling events from the receiver | ||
| self.handlerthread = HandlerThread("handlerthread") | ||
|
|
||
| # create a listener | ||
| self.receiver_filter = IntentFilter() | ||
| for x in resolved_actions: | ||
| self.receiver_filter.addAction(x) | ||
| for x in resolved_categories: | ||
| self.receiver_filter.addCategory(x) | ||
|
|
||
| def start(self): | ||
| self.handlerthread.start() | ||
| self.handler = Handler(self.handlerthread.getLooper()) | ||
| self.context.registerReceiver( | ||
| self, | ||
| self.receiver_filter, | ||
| None, # type: ignore | ||
| self.handler, | ||
| ) | ||
|
|
||
| def stop(self): | ||
| self.context.unregisterReceiver(self) | ||
| self.handlerthread.quit() | ||
|
|
||
| @Override(jvoid, [Context, Intent]) | ||
| @external_thread_callback | ||
| def onReceive(self, context: Context, intent: Intent): | ||
| logger.debug(f"BroadcastReceiver received intent: {intent}") | ||
| self.callback(context, intent) |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Modern systems have file watchers that does this automatically, so I've never needed to manually reload rules.
Maybe there could be a race condition though in a script, so I guess it doesn't hurt.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or since this is CI, just get rid of the udev stuff and just run
sudo chmoddirectly.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just followed the recommendations from Github: https://github.blog/changelog/2024-04-02-github-actions-hardware-accelerated-android-virtualization-now-available/
I added the link also to the source code, so that the source of these commands is clear.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just because they recommended it doesn't mean they understood it. 😉