From b89734a87dc60d9ba782be1748db165de2f84514 Mon Sep 17 00:00:00 2001 From: Dan Nicholson Date: Fri, 21 Oct 2022 09:39:10 -0600 Subject: [PATCH 1/2] Add support for Google Services gradle plugin The Google Services gradle plugin[1] helps enable use of Google services in Android apps. Since this requires a `google-services.json` file to be copied into the build directory, it needs to be a separate option in addition to enabling the plugin in the `build.gradle` file. 1. https://developers.google.com/android/guides/google-services-plugin --- doc/source/buildoptions.rst | 9 +++++++++ .../bootstraps/common/build/build.py | 18 ++++++++++++++++++ .../common/build/templates/build.tmpl.gradle | 6 ++++++ pythonforandroid/toolchain.py | 9 ++++++++- 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/doc/source/buildoptions.rst b/doc/source/buildoptions.rst index d9f97175a2..3cde9e9b5e 100644 --- a/doc/source/buildoptions.rst +++ b/doc/source/buildoptions.rst @@ -91,6 +91,9 @@ options (this list may not be exhaustive): - ``--add-source``: Add a source directory to the app's Java code. - ``--no-compile-pyo``: Do not optimise .py files to .pyo. - ``--enable-androidx``: Enable AndroidX support library. +- ``--enable-google-services``: Enable the Google Services Gradle plugin. + This option requires a ``google-services.json`` file in root of the + project directory. webview @@ -152,6 +155,9 @@ ready. - ``add-source``: Add a source directory to the app's Java code. - ``--port``: The port on localhost that the WebView will access. Defaults to 5000. +- ``--enable-google-services``: Enable the Google Services Gradle plugin. + This option requires a ``google-services.json`` file in root of the + project directory. service_library @@ -177,6 +183,9 @@ systems and frameworks. - ``--add-jar``: The path to a .jar file to include in the APK. To include multiple jar files, pass this argument multiple times. - ``add-source``: Add a source directory to the app's Java code. +- ``--enable-google-services``: Enable the Google Services Gradle plugin. + This option requires a ``google-services.json`` file in root of the + project directory. Requirements blacklist (APK size optimization) diff --git a/pythonforandroid/bootstraps/common/build/build.py b/pythonforandroid/bootstraps/common/build/build.py index 300d1ce5e9..58eb453d27 100755 --- a/pythonforandroid/bootstraps/common/build/build.py +++ b/pythonforandroid/bootstraps/common/build/build.py @@ -548,6 +548,9 @@ def make_package(args): if args.fileprovider_paths: shutil.copy(args.fileprovider_paths, join(res_dir, "xml/file_paths.xml")) + if args.enable_google_services: + shutil.copy(args.google_services_json, 'src/google-services.json') + # gradle build templates render( 'build.tmpl.gradle', @@ -864,6 +867,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') + ap.add_argument('--enable-google-services', dest='enable_google_services', + action='store_true', + help=('Enable the Google Services Gradle plugin. ' + 'This requires a google-services.json in the root ' + 'of the project.')) + ap.add_argument('--google-services-json', dest='google_services_json', + default='google-services.json', + help='Path to google-services.json file') + # Put together arguments, and add those from .p4a config file: if args is None: args = sys.argv[1:] @@ -949,6 +961,12 @@ def _read_configuration(): '--launcher (SDL2 bootstrap only)' + 'to have something to launch inside the .apk!') sys.exit(1) + + if args.enable_google_services and not exists(args.google_services_json): + print('You must provide a google-services.json file for ' + '--enable-google-services') + sys.exit(1) + make_package(args) return args diff --git a/pythonforandroid/bootstraps/common/build/templates/build.tmpl.gradle b/pythonforandroid/bootstraps/common/build/templates/build.tmpl.gradle index 696682075c..b12497288e 100644 --- a/pythonforandroid/bootstraps/common/build/templates/build.tmpl.gradle +++ b/pythonforandroid/bootstraps/common/build/templates/build.tmpl.gradle @@ -6,6 +6,9 @@ buildscript { } dependencies { classpath 'com.android.tools.build:gradle:7.1.2' + {% if args.enable_google_services %} + classpath 'com.google.gms:google-services:4.3.14' + {% endif %} } } @@ -27,6 +30,9 @@ apply plugin: 'com.android.library' {% else %} apply plugin: 'com.android.application' {% endif %} +{% if args.enable_google_services %} +apply plugin: 'com.google.gms.google-services' +{% endif %} android { compileSdkVersion {{ android_api }} diff --git a/pythonforandroid/toolchain.py b/pythonforandroid/toolchain.py index 479f48f7df..fe9d8ea3c5 100644 --- a/pythonforandroid/toolchain.py +++ b/pythonforandroid/toolchain.py @@ -552,6 +552,10 @@ def add_parser(subparsers, *args, **kwargs): parser_packaging.add_argument( '--signkeypw', dest='signkeypw', action='store', default=None, help='Password for key alias') + parser_packaging.add_argument( + '--google-services-json', dest='google_services_json', + default='google-services.json', + help='Path to google-services.json file') add_parser( subparsers, @@ -627,6 +631,8 @@ def add_parser(subparsers, *args, **kwargs): args.unknown_args += ["--activity-class-name", args.activity_class_name] if hasattr(args, "service_class_name") and args.service_class_name != 'org.kivy.android.PythonService': args.unknown_args += ["--service-class-name", args.service_class_name] + if hasattr(args, "google_services_json") and args.google_services_json: + args.unknown_args += ["--google-services-json", args.google_services_json] self.args = args @@ -990,7 +996,8 @@ def _fix_args(args): fix_args = ('--dir', '--private', '--add-jar', '--add-source', '--whitelist', '--blacklist', '--presplash', '--icon', - '--icon-bg', '--icon-fg', '--fileprovider-paths') + '--icon-bg', '--icon-fg', '--fileprovider-paths', + '--google-services-json') unknown_args = args.unknown_args for asset in args.assets: From 8a506eff5261635d987bc9b578a021c7d84d22e5 Mon Sep 17 00:00:00 2001 From: Dan Nicholson Date: Fri, 21 Oct 2022 09:56:53 -0600 Subject: [PATCH 2/2] Add support for additional Gradle plugins Some Google Android features such as Firebase Crashlytics are enabled with Gradle plugins. Add support for specifying additional plugins in `build.gradle`. --- doc/source/buildoptions.rst | 6 ++++++ pythonforandroid/bootstraps/common/build/build.py | 14 ++++++++++++++ .../common/build/templates/build.tmpl.gradle | 6 ++++++ 3 files changed, 26 insertions(+) diff --git a/doc/source/buildoptions.rst b/doc/source/buildoptions.rst index 3cde9e9b5e..22a7aa61e5 100644 --- a/doc/source/buildoptions.rst +++ b/doc/source/buildoptions.rst @@ -94,6 +94,8 @@ options (this list may not be exhaustive): - ``--enable-google-services``: Enable the Google Services Gradle plugin. This option requires a ``google-services.json`` file in root of the project directory. +- ``--add-gradle-plugins``: Add a plugin for gradle. The format of the option + is ``:``. The option can be specified multiple times. webview @@ -158,6 +160,8 @@ ready. - ``--enable-google-services``: Enable the Google Services Gradle plugin. This option requires a ``google-services.json`` file in root of the project directory. +- ``--add-gradle-plugins``: Add a plugin for gradle. The format of the option + is ``:``. The option can be specified multiple times. service_library @@ -186,6 +190,8 @@ systems and frameworks. - ``--enable-google-services``: Enable the Google Services Gradle plugin. This option requires a ``google-services.json`` file in root of the project directory. +- ``--add-gradle-plugin``: Add a plugin for gradle. The format of the option + is ``:``. The option can be specified multiple times. Requirements blacklist (APK size optimization) diff --git a/pythonforandroid/bootstraps/common/build/build.py b/pythonforandroid/bootstraps/common/build/build.py index 58eb453d27..aef357b1ca 100755 --- a/pythonforandroid/bootstraps/common/build/build.py +++ b/pythonforandroid/bootstraps/common/build/build.py @@ -551,6 +551,13 @@ def make_package(args): if args.enable_google_services: shutil.copy(args.google_services_json, 'src/google-services.json') + # Convert the gradle_plugins args to a list of dicts with id and + # classpath keys. + gradle_plugins = [ + dict(zip(('id', 'classpath'), spec.split(':', maxsplit=1))) + for spec in args.gradle_plugins + ] + # gradle build templates render( 'build.tmpl.gradle', @@ -562,6 +569,7 @@ def make_package(args): build_tools_version=build_tools_version, debug_build="debug" in args.build_mode, is_library=(get_bootstrap_name() == 'service_library'), + gradle_plugins=gradle_plugins, ) # gradle properties @@ -764,6 +772,12 @@ def parse_args_and_make_package(args=None): default=[], action='append', help='Ddd a repository for gradle') + ap.add_argument('--add-gradle-plugin', dest='gradle_plugins', + default=[], + action='append', + help=('Add a plugin for gradle. The format of the option ' + 'is :. The option can be ' + 'specified multiple times.')) ap.add_argument('--add-packaging-option', dest='packaging_options', default=[], action='append', diff --git a/pythonforandroid/bootstraps/common/build/templates/build.tmpl.gradle b/pythonforandroid/bootstraps/common/build/templates/build.tmpl.gradle index b12497288e..71c8c36e25 100644 --- a/pythonforandroid/bootstraps/common/build/templates/build.tmpl.gradle +++ b/pythonforandroid/bootstraps/common/build/templates/build.tmpl.gradle @@ -9,6 +9,9 @@ buildscript { {% if args.enable_google_services %} classpath 'com.google.gms:google-services:4.3.14' {% endif %} + {% for plugin in gradle_plugins %} + classpath '{{ plugin.classpath }}' + {% endfor %} } } @@ -33,6 +36,9 @@ apply plugin: 'com.android.application' {% if args.enable_google_services %} apply plugin: 'com.google.gms.google-services' {% endif %} +{% for plugin in gradle_plugins %} +apply plugin: '{{ plugin.id }}' +{% endfor %} android { compileSdkVersion {{ android_api }}