Skip to content

Commit

Permalink
Merge pull request #2740 from misl6/release-2023.01.28
Browse files Browse the repository at this point in the history
Release 2023.01.28
  • Loading branch information
misl6 authored Jan 28, 2023
2 parents cc6481b + 5b45f40 commit ee9c257
Show file tree
Hide file tree
Showing 15 changed files with 427 additions and 72 deletions.
27 changes: 27 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,32 @@
# Changelog

## [v2023.01.28](https://github.com/kivy/python-for-android/tree/v2023.01.28) (2023-01-28)

[Full Changelog](https://github.com/kivy/python-for-android/compare/v2022.12.20...v2023.01.28)

**Closed issues:**

- Python
[\#2737](https://github.com/kivy/python-for-android/issues/2737)
- AndroidX Issue [\#2736](https://github.com/kivy/python-for-android/issues/2736)
- Kivy build failed [\#2735](https://github.com/kivy/python-for-android/issues/2735)
- Can't build apk using READ\_EXTERNAL\_STORAGE, WRITE\_EXTERNAL\_STORAGE in buildozer.spec [\#2732](https://github.com/kivy/python-for-android/issues/2732)
- BUILD FAILURE: No main.py\(o\) found in your app directory. [\#2731](https://github.com/kivy/python-for-android/issues/2731)
- Your app currently targets API level 30 and must target at least API level 31 to ensure that it is built on the latest APIs optimised for security and performance. Change your app's target API level to at least 31 [\#2729](https://github.com/kivy/python-for-android/issues/2729)
- Your app currently targets API level 30 and must target at least API level 31 to ensure that it is built on the latest APIs optimised for security and performance. Change your app's target API level to at least 31 [\#2727](https://github.com/kivy/python-for-android/issues/2727)
- `sh.CommandNotFound: ./download.sh` [\#2726](https://github.com/kivy/python-for-android/issues/2726)
- Setting `android:screenOrientation` via `--orientation` has no effect when targeting API 31 [\#2724](https://github.com/kivy/python-for-android/issues/2724)
- \[Question\]: How to set 'compileSdkVersion' to 31 or higher. [\#2722](https://github.com/kivy/python-for-android/issues/2722)
- Bug in the keyboard event listener [\#2423](https://github.com/kivy/python-for-android/issues/2423)

**Merged pull requests:**

- Implements `--manifest-orientation` and changes how `--orientation` works so we can now pass the setting to the SDL orientation hint [\#2739](https://github.com/kivy/python-for-android/pull/2739) ([misl6](https://github.com/misl6))
- Update \_\_init\_\_.py from `scrypt` recipe [\#2738](https://github.com/kivy/python-for-android/pull/2738) ([FilipeMarch](https://github.com/FilipeMarch))
- Apply a patch from SDL upstream that fixes orientation settings [\#2730](https://github.com/kivy/python-for-android/pull/2730) ([misl6](https://github.com/misl6))
- Support permission properties \(`maxSdkVersion` and `usesPermissionFlags`\) + remove `WRITE_EXTERNAL_STORAGE` permission, which has been previously declared by default [\#2725](https://github.com/kivy/python-for-android/pull/2725) ([misl6](https://github.com/misl6))
- Merge master in develop [\#2721](https://github.com/kivy/python-for-android/pull/2721) ([misl6](https://github.com/misl6))

## [v2022.12.20](https://github.com/kivy/python-for-android/tree/v2022.12.20) (2022-12-20)

[Full Changelog](https://github.com/kivy/python-for-android/compare/v2022.09.04...v2022.12.20)
Expand Down
6 changes: 4 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ testapps-with-numpy: virtualenv
. $(ACTIVATE) && cd testapps/on_device_unit_tests/ && \
python setup.py apk --sdk-dir $(ANDROID_SDK_HOME) --ndk-dir $(ANDROID_NDK_HOME) \
--requirements libffi,sdl2,pyjnius,kivy,python3,openssl,requests,urllib3,chardet,idna,sqlite3,setuptools,numpy \
--arch=armeabi-v7a --arch=arm64-v8a --arch=x86_64 --arch=x86
--arch=armeabi-v7a --arch=arm64-v8a --arch=x86_64 --arch=x86 \
--permission "(name=android.permission.WRITE_EXTERNAL_STORAGE;maxSdkVersion=18)" --permission "(name=android.permission.INTERNET)"

testapps-with-scipy: virtualenv
. $(ACTIVATE) && cd testapps/on_device_unit_tests/ && \
Expand All @@ -53,7 +54,8 @@ testapps-with-numpy-aab: virtualenv
. $(ACTIVATE) && cd testapps/on_device_unit_tests/ && \
python setup.py aab --sdk-dir $(ANDROID_SDK_HOME) --ndk-dir $(ANDROID_NDK_HOME) \
--requirements libffi,sdl2,pyjnius,kivy,python3,openssl,requests,urllib3,chardet,idna,sqlite3,setuptools,numpy \
--arch=armeabi-v7a --arch=arm64-v8a --arch=x86_64 --arch=x86 --release
--arch=armeabi-v7a --arch=arm64-v8a --arch=x86_64 --arch=x86 --release \
--permission "(name=android.permission.WRITE_EXTERNAL_STORAGE;maxSdkVersion=18)" --permission "(name=android.permission.INTERNET)"

testapps-service_library-aar: virtualenv
. $(ACTIVATE) && cd testapps/on_device_unit_tests/ && \
Expand Down
54 changes: 39 additions & 15 deletions doc/source/buildoptions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,36 @@ options (this list may not be exhaustive):
- ``--package``: The Java package name for your project. e.g. ``org.example.yourapp``.
- ``--name``: The app name.
- ``--version``: The version number.
- ``--orientation``: Usually one of ``portait``, ``landscape``,
``sensor`` to automatically rotate according to the device
orientation, or ``user`` to do the same but obeying the user's
settings. The full list of valid options is given under
``android:screenOrientation`` in the `Android documentation
<https://developer.android.com/guide/topics/manifest/activity-element.html>`__.
- ``--orientation``: The orientations that the app will display in.
(Available options are ``portrait``, ``landscape``, ``portrait-reverse``, ``landscape-reverse``).
Since Android ignores ``android:screenOrientation`` when in multi-window mode
(Which is the default on Android 12+), this option will also set the window orientation hints
for the SDL bootstrap. If multiple orientations are given,
``android:screenOrientation`` will be set to ``unspecified``.
- ``--manifest-orientation``: The orientation that will be set for the ``android:screenOrientation``
attribute of the activity in the ``AndroidManifest.xml`` file. If not set, the value
will be synthesized from the ``--orientation`` option.
The full list of valid options is given under ``android:screenOrientation``
in the `Android documentation <https://developer.android.com/guide/topics/manifest/activity-element.html>`__.
- ``--icon``: A path to the png file to use as the application icon.
- ``--permission``: A permission name for the app,
e.g. ``--permission VIBRATE``. For multiple permissions, add
multiple ``--permission`` arguments.
- ``--permission``: A permission that needs to be declared into the App ``AndroidManifest.xml``.
For multiple permissions, add multiple ``--permission`` arguments.

.. Note ::
``--permission`` accepts the following syntaxes:
``--permission (name=android.permission.WRITE_EXTERNAL_STORAGE;maxSdkVersion=18)``
or ``--permission android.permission.WRITE_EXTERNAL_STORAGE``.
The first syntax is used to set additional properties to the permission
(``android:maxSdkVersion`` and ``android:usesPermissionFlags`` are the only ones supported for now).
The second one can be used when there's no need to add any additional properties.
.. Warning ::
The syntax ``--permission VIBRATE`` (only the permission name, without the prefix),
is also supported for backward compatibility, but it will be removed in the future.
- ``--meta-data``: Custom key=value pairs to add in the application metadata.
- ``--presplash``: A path to the image file to use as a screen while
the application is loading.
Expand Down Expand Up @@ -121,12 +141,16 @@ ready.
- ``--package``: The Java package name for your project. e.g. ``org.example.yourapp``.
- ``--name``: The app name.
- ``--version``: The version number.
- ``--orientation``: Usually one of ``portait``, ``landscape``,
``sensor`` to automatically rotate according to the device
orientation, or ``user`` to do the same but obeying the user's
settings. The full list of valid options is given under
``android:screenOrientation`` in the `Android documentation
<https://developer.android.com/guide/topics/manifest/activity-element.html>`__.
- ``--orientation``: The orientations that the app will display in.
(Available options are ``portrait``, ``landscape``, ``portrait-reverse``, ``landscape-reverse``).
Since Android ignores ``android:screenOrientation`` when in multi-window mode
(Which is the default on Android 12+), this setting is not guaranteed to work, and
you should consider to implement a custom orientation change handler in your app.
- ``--manifest-orientation``: The orientation that will be set in the ``android:screenOrientation``
attribute of the activity in the ``AndroidManifest.xml`` file. If not set, the value
will be synthesized from the ``--orientation`` option.
The full list of valid options is given under ``android:screenOrientation``
in the `Android documentation <https://developer.android.com/guide/topics/manifest/activity-element.html>`__.
- ``--icon``: A path to the png file to use as the application icon.
- ``--permission``: A permission name for the app,
e.g. ``--permission VIBRATE``. For multiple permissions, add
Expand Down
2 changes: 1 addition & 1 deletion pythonforandroid/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '2022.12.20'
__version__ = '2023.01.28'
3 changes: 3 additions & 0 deletions pythonforandroid/bdistapk.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ def finalize_options(self):
if option == 'permissions':
for perm in value:
sys.argv.append('--permission={}'.format(perm))
elif option == 'orientation':
for orient in value:
sys.argv.append('--orientation={}'.format(orient))
elif value in (None, 'None'):
sys.argv.append('--{}'.format(option))
else:
Expand Down
157 changes: 127 additions & 30 deletions pythonforandroid/bootstraps/common/build/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,6 @@ def get_bootstrap_name():

curdir = dirname(__file__)

PYTHON = get_hostpython()
if PYTHON is not None and not exists(PYTHON):
PYTHON = None

BLACKLIST_PATTERNS = [
# code versionning
'^*.hg/*',
Expand All @@ -75,9 +71,19 @@ def get_bootstrap_name():
]

WHITELIST_PATTERNS = []
if get_bootstrap_name() in ('sdl2', 'webview', 'service_only'):
WHITELIST_PATTERNS.append('pyconfig.h')

if os.environ.get("P4A_BUILD_IS_RUNNING_UNITTESTS", "0") != "1":
PYTHON = get_hostpython()
_bootstrap_name = get_bootstrap_name()
else:
PYTHON = "python3"
_bootstrap_name = "sdl2"

if PYTHON is not None and not exists(PYTHON):
PYTHON = None

if _bootstrap_name in ('sdl2', 'webview', 'service_only'):
WHITELIST_PATTERNS.append('pyconfig.h')

environment = jinja2.Environment(loader=jinja2.FileSystemLoader(
join(curdir, 'templates')))
Expand Down Expand Up @@ -243,8 +249,8 @@ def make_package(args):
with open(os.path.join(env_vars_tarpath, "p4a_env_vars.txt"), "w") as f:
if hasattr(args, "window"):
f.write("P4A_IS_WINDOWED=" + str(args.window) + "\n")
if hasattr(args, "orientation"):
f.write("P4A_ORIENTATION=" + str(args.orientation) + "\n")
if hasattr(args, "sdl_orientation_hint"):
f.write("KIVY_ORIENTATION=" + str(args.sdl_orientation_hint) + "\n")
f.write("P4A_NUMERIC_VERSION=" + str(args.numeric_version) + "\n")
f.write("P4A_MINSDK=" + str(args.min_sdk_version) + "\n")

Expand Down Expand Up @@ -646,20 +652,92 @@ def make_package(args):
subprocess.check_output(patch_command)


def parse_args_and_make_package(args=None):
global BLACKLIST_PATTERNS, WHITELIST_PATTERNS, PYTHON
def parse_permissions(args_permissions):
if args_permissions and isinstance(args_permissions[0], list):
args_permissions = [p for perm in args_permissions for p in perm]

def _is_advanced_permission(permission):
return permission.startswith("(") and permission.endswith(")")

def _decode_advanced_permission(permission):
SUPPORTED_PERMISSION_PROPERTIES = ["name", "maxSdkVersion", "usesPermissionFlags"]
_permission_args = permission[1:-1].split(";")
_permission_args = (arg.split("=") for arg in _permission_args)
advanced_permission = dict(_permission_args)

if "name" not in advanced_permission:
raise ValueError("Advanced permission must have a name property")

for key in advanced_permission.keys():
if key not in SUPPORTED_PERMISSION_PROPERTIES:
raise ValueError(
f"Property '{key}' is not supported. "
"Advanced permission only supports: "
f"{', '.join(SUPPORTED_PERMISSION_PROPERTIES)} properties"
)

return advanced_permission

_permissions = []
for permission in args_permissions:
if _is_advanced_permission(permission):
_permissions.append(_decode_advanced_permission(permission))
else:
if "." in permission:
_permissions.append(dict(name=permission))
else:
_permissions.append(dict(name=f"android.permission.{permission}"))
return _permissions


def get_sdl_orientation_hint(orientations):
SDL_ORIENTATION_MAP = {
"landscape": "LandscapeLeft",
"portrait": "Portrait",
"portrait-reverse": "PortraitUpsideDown",
"landscape-reverse": "LandscapeRight",
}
return " ".join(
[SDL_ORIENTATION_MAP[x] for x in orientations if x in SDL_ORIENTATION_MAP]
)


def get_manifest_orientation(orientations, manifest_orientation=None):
# If the user has specifically set an orientation to use in the manifest,
# use that.
if manifest_orientation is not None:
return manifest_orientation

# If multiple or no orientations are specified, use unspecified in the manifest,
# as we can only specify one orientation in the manifest.
if len(orientations) != 1:
return "unspecified"

# Convert the orientation to a value that can be used in the manifest.
# If the specified orientation is not supported, use unspecified.
MANIFEST_ORIENTATION_MAP = {
"landscape": "landscape",
"portrait": "portrait",
"portrait-reverse": "reversePortrait",
"landscape-reverse": "reverseLandscape",
}
return MANIFEST_ORIENTATION_MAP.get(orientations[0], "unspecified")


def get_dist_ndk_min_api_level():
# Get the default minsdk, equal to the NDK API that this dist is built against
try:
with open('dist_info.json', 'r') as fileh:
info = json.load(fileh)
default_min_api = int(info['ndk_api'])
ndk_api = default_min_api
ndk_api = int(info['ndk_api'])
except (OSError, KeyError, ValueError, TypeError):
print('WARNING: Failed to read ndk_api from dist info, defaulting to 12')
default_min_api = 12 # The old default before ndk_api was introduced
ndk_api = 12
ndk_api = 12 # The old default before ndk_api was introduced
return ndk_api


def create_argument_parser():
ndk_api = get_dist_ndk_min_api_level()
import argparse
ap = argparse.ArgumentParser(description='''\
Package a Python application for Android (using
Expand Down Expand Up @@ -742,19 +820,21 @@ def parse_args_and_make_package(args=None):
ap.add_argument('--window', dest='window', action='store_true',
default=False,
help='Indicate if the application will be windowed')
ap.add_argument('--manifest-orientation', dest='manifest_orientation',
help=('The orientation that will be set in the '
'android:screenOrientation attribute of the activity '
'in the AndroidManifest.xml file. If not set, '
'the value will be synthesized from the --orientation option.'))
ap.add_argument('--orientation', dest='orientation',
default='portrait',
help=('The orientation that the game will '
'display in. '
'Usually one of "landscape", "portrait", '
'"sensor", or "user" (the same as "sensor" '
'but obeying the '
'user\'s Android rotation setting). '
'The full list of options is given under '
'android_screenOrientation at '
'https://developer.android.com/guide/'
'topics/manifest/'
'activity-element.html'))
action="append", default=[],
choices=['portrait', 'landscape', 'landscape-reverse', 'portrait-reverse'],
help=('The orientations that the app will display in. '
'Since Android ignores android:screenOrientation '
'when in multi-window mode (Which is the default on Android 12+), '
'this option will also set the window orientation hints '
'for apps using the (default) SDL bootstrap.'
'If multiple orientations are given, android:screenOrientation '
'will be set to "unspecified"'))

ap.add_argument('--enable-androidx', dest='enable_androidx',
action='store_true',
Expand Down Expand Up @@ -809,9 +889,9 @@ def parse_args_and_make_package(args=None):
ap.add_argument('--sdk', dest='sdk_version', default=-1,
type=int, help=('Deprecated argument, does nothing'))
ap.add_argument('--minsdk', dest='min_sdk_version',
default=default_min_api, type=int,
default=ndk_api, type=int,
help=('Minimum Android SDK version that the app supports. '
'Defaults to {}.'.format(default_min_api)))
'Defaults to {}.'.format(ndk_api)))
ap.add_argument('--allow-minsdk-ndkapi-mismatch', default=False,
action='store_true',
help=('Allow the --minsdk argument to be different from '
Expand Down Expand Up @@ -874,6 +954,15 @@ def parse_args_and_make_package(args=None):
ap.add_argument('--activity-class-name', dest='activity_class_name', default=DEFAULT_PYTHON_ACTIVITY_JAVA_CLASS,
help='The full java class name of the main activity')

return ap


def parse_args_and_make_package(args=None):
global BLACKLIST_PATTERNS, WHITELIST_PATTERNS, PYTHON

ndk_api = get_dist_ndk_min_api_level()
ap = create_argument_parser()

# Put together arguments, and add those from .p4a config file:
if args is None:
args = sys.argv[1:]
Expand Down Expand Up @@ -918,8 +1007,14 @@ def _read_configuration():
'deprecated and does nothing.')
args.sdk_version = -1 # ensure it is not used

if args.permissions and isinstance(args.permissions[0], list):
args.permissions = [p for perm in args.permissions for p in perm]
args.permissions = parse_permissions(args.permissions)

args.manifest_orientation = get_manifest_orientation(
args.orientation, args.manifest_orientation
)

if get_bootstrap_name() == "sdl2":
args.sdl_orientation_hint = get_sdl_orientation_hint(args.orientation)

if args.res_xmls and isinstance(args.res_xmls[0], list):
args.res_xmls = [x for res in args.res_xmls for x in res]
Expand Down Expand Up @@ -959,4 +1054,6 @@ def _read_configuration():


if __name__ == "__main__":
if get_bootstrap_name() in ('sdl2', 'webview', 'service_only'):
WHITELIST_PATTERNS.append('pyconfig.h')
parse_args_and_make_package()
Loading

0 comments on commit ee9c257

Please sign in to comment.