Skip to content
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

python-for-android backend #422

Merged
merged 43 commits into from
Oct 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
7a0ed93
Added a backend for python-for-android
xloem Jan 8, 2021
7aa7532
Organised a little bit and added docs
xloem Jan 27, 2021
1387aec
Merge remote-tracking branch 'origin/develop' into pr/xloem/422
dlech Oct 8, 2021
93d1bf0
p2a: fix build for recent upsteam changes
dlech Oct 8, 2021
137ede3
examples/kivy: add .gitignore
dlech Oct 8, 2021
e2fde51
p4a: fix scanner discovered_devices property
dlech Oct 8, 2021
e6fa866
p4a: change is_connected from async to property
dlech Oct 8, 2021
bee5f19
p4a: fix return value of is_connected
dlech Oct 9, 2021
6805e4c
p4a: implement client mtu_size property
dlech Oct 8, 2021
3ed3830
p4a: disconnect on connection failure
dlech Oct 8, 2021
c581b51
p4a: raise exception on disconnect failure
dlech Oct 8, 2021
43a96df
p4a: update example to use asyncio.run()
dlech Oct 8, 2021
ccc4f15
p4a: update example to use context manager
dlech Oct 8, 2021
4acd986
p4a: use device.name in example
dlech Oct 8, 2021
ead6bf3
p4a: fix missing overrides
dlech Oct 8, 2021
9b82c81
p4a: update example README
dlech Oct 8, 2021
b663779
github: add job for building android
dlech Oct 8, 2021
ab166a9
[p4a] remove shebang from android and clarify that kivy is cross-plat…
xloem Oct 9, 2021
ba9469a
[p4a] use error strings from bleak.exc
xloem Oct 9, 2021
6c450fa
[p4a] remove cached java constants
xloem Oct 9, 2021
497638e
[p4a] removed descriptor handle warning
xloem Oct 9, 2021
ea6fea0
Update examples/kivy/main.py
xloem Oct 9, 2021
ff4ea00
[p4a] remove unimplemented "adapter" kwparam
xloem Oct 9, 2021
a813f91
[p4a] iterate java lists as iterables
xloem Oct 9, 2021
42959f8
[p4a] migrate from .format to f-strings
xloem Oct 9, 2021
01a7a6e
[p4a] black formatted
xloem Oct 9, 2021
bceb130
[p4a] do not convert connection states to strings
xloem Oct 9, 2021
c6375ef
[p4a] remove unused imports from descriptor.py
xloem Oct 9, 2021
052917d
Add common profile and service protocol error codes.
xloem Oct 9, 2021
0ba46b8
[p4a] Use new error codes and normalise capitalisation.
xloem Oct 9, 2021
af67c26
[p4a] use caching in github workflow
xloem Oct 10, 2021
6c1e5e9
[p4a] ignore android imports during autodoc
xloem Oct 10, 2021
39e096a
[p4a] clarify how to rebuild bleak in the example
xloem Oct 10, 2021
a065013
[p4a] clean github action prior to build conditional on cache hit per…
xloem Oct 10, 2021
76fd713
Revert "[p4a] ignore android imports during autodoc"
xloem Oct 10, 2021
f19d515
[p4a] add android and jnius autodoc_mock_imports
xloem Oct 10, 2021
775924f
[p4a] scanner: initialise __adapter in __init__ for consistency
xloem Oct 10, 2021
25f273d
Merge branch 'develop' into pr/xloem/422
dlech Oct 17, 2021
48b79a4
p4a: remove CONTROLLER_ERROR_CODES from error code table
dlech Oct 17, 2021
0623222
p4a: remove unused import
dlech Oct 17, 2021
0aa39d4
p4a: spelling
dlech Oct 17, 2021
6939fb0
p4a: convert SCAN_FAILED_NAMES to IntEnum
dlech Oct 17, 2021
9598990
p4a: use bytes in advertising data
dlech Oct 17, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion .github/workflows/build_and_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ on:
branches: [ master, develop ]

jobs:
build_linux:
build_desktop:
name: "Build and test"
runs-on: ${{ matrix.os }}
strategy:
Expand Down Expand Up @@ -36,3 +36,27 @@ jobs:
path: junit/test-results-${{ matrix.os }}-${{ matrix.python-version }}.xml
# Use always() to always run this step to publish test results when there are test failures
if: ${{ always() }}
build_android:
name: "Build Android"
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- name: Upgrade pip. setuptools and wheel
run: python -m pip install --upgrade pip setuptools wheel
- name: Install dependencies
run: pip install buildozer cython
- name: Cache buildozer files
uses: actions/cache@v2
id: buildozer-cache
with:
path: |
~/.buildozer
examples/kivy/.buildozer
key: build-cache-buildozer
- name: Clean bleak recipe for cache
if: steps.buildozer-cache.outputs.cache-hit == 'true'
working-directory: examples/kivy
run: buildozer android p4a -- clean-recipe-build --local-recipes $(pwd)/../../bleak/backends/p4android/recipes bleak
- name: Build Kivy example
working-directory: examples/kivy
run: buildozer android debug
xloem marked this conversation as resolved.
Show resolved Hide resolved
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Added
* Added ``register_uuids()`` to augment the uuid-to-description mapping.
* Added support for Python 3.10.
* Added ``force_indicate`` keyword argument for WinRT backend client's ``start_notify`` method. Fixes #526.
* Added python-for-android backend.

Changed
-------
Expand Down
1 change: 1 addition & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ Features
* Supports Windows 10, version 16299 (Fall Creators Update) or greater
* Supports Linux distributions with BlueZ >= 5.43
* OS X/macOS support via Core Bluetooth API, from at least OS X version 10.11
* Android backend compatible with python-for-android

Bleak supports reading, writing and getting notifications from
GATT servers, as well as a function for discovering BLE devices.
Expand Down
7 changes: 7 additions & 0 deletions bleak/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@

if _on_rtd:
pass
elif os.environ.get("P4A_BOOTSTRAP") is not None:
from bleak.backends.p4android.scanner import (
BleakScannerP4Android as BleakScanner,
) # noqa: F401
from bleak.backends.p4android.client import (
BleakClientP4Android as BleakClient,
) # noqa: F401
elif platform.system() == "Linux":
if not _on_ci and not check_bluez_version(5, 43):
raise BleakError("Bleak requires BlueZ >= 5.43.")
Expand Down
Empty file.
90 changes: 90 additions & 0 deletions bleak/backends/p4android/characteristic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
from uuid import UUID
from typing import Union, List

from bleak.backends.characteristic import BleakGATTCharacteristic
from bleak.backends.descriptor import BleakGATTDescriptor
from bleak.exc import BleakError


from . import defs


class BleakGATTCharacteristicP4Android(BleakGATTCharacteristic):
"""GATT Characteristic implementation for the python-for-android backend"""

def __init__(self, java, service_uuid: str, service_handle: int):
super(BleakGATTCharacteristicP4Android, self).__init__(java)
self.__uuid = self.obj.getUuid().toString()
self.__handle = self.obj.getInstanceId()
self.__service_uuid = service_uuid
self.__service_handle = service_handle
self.__descriptors = []
self.__notification_descriptor = None

self.__properties = [
name
for flag, name in defs.CHARACTERISTIC_PROPERTY_DBUS_NAMES.items()
if flag & self.obj.getProperties()
]

@property
def service_uuid(self) -> str:
"""The uuid of the Service containing this characteristic"""
return self.__service_uuid

@property
def service_handle(self) -> int:
"""The integer handle of the Service containing this characteristic"""
return int(self.__service_handle)

@property
def handle(self) -> int:
"""The handle of this characteristic"""
return self.__handle

@property
def uuid(self) -> str:
"""The uuid of this characteristic"""
return self.__uuid

@property
def properties(self) -> List:
"""Properties of this characteristic"""
return self.__properties

@property
def descriptors(self) -> List:
"""List of descriptors for this service"""
return self.__descriptors

def get_descriptor(
self, specifier: Union[str, UUID]
) -> Union[BleakGATTDescriptor, None]:
"""Get a descriptor by UUID (str or uuid.UUID)"""
if isinstance(specifier, int):
raise BleakError(
"The Android Bluetooth API does not provide access to descriptor handles."
)

matches = [
descriptor
for descriptor in self.descriptors
if descriptor.uuid == str(specifier)
]
if len(matches) == 0:
return None
return matches[0]

def add_descriptor(self, descriptor: BleakGATTDescriptor):
"""Add a :py:class:`~BleakGATTDescriptor` to the characteristic.

Should not be used by end user, but rather by `bleak` itself.
"""
self.__descriptors.append(descriptor)
if descriptor.uuid == defs.CLIENT_CHARACTERISTIC_CONFIGURATION_UUID:
self.__notification_descriptor = descriptor

@property
def notification_descriptor(self) -> BleakGATTDescriptor:
"""The notification descriptor. Mostly needed by `bleak`, not by end user"""
return self.__notification_descriptor
Loading