changeset 61:0b7f10de416e

android: android build first draft: - added buildozer.spec - added src/sat.conf which is the configuration used on android (FIXME: need to rename/move it) - small hack to change loading paths on android - sys.platform is set to android when kivy_utils.platform is set to android - softinput_mode is set to "below_target", so field are not hidden when virtual keyboard appears Note: using org.goffi.cagou instead of org.salut-a-toi.cagou for package domain because the dash ("-") is causing trouble to buildozer. This need to be fixed.
author Goffi <goffi@goffi.org>
date Sun, 04 Dec 2016 18:21:23 +0100
parents 35abe494e6c7
children 1922506846be
files src/buildozer.spec src/cagou/core/cagou_main.py src/sat.conf
diffstat 3 files changed, 267 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/buildozer.spec	Sun Dec 04 18:21:23 2016 +0100
@@ -0,0 +1,236 @@
+[app]
+
+# (str) Title of your application
+title = Cagou
+
+# (str) Package name
+package.name = cagou
+
+# (str) Package domain (needed for android/ios packaging)
+package.domain = org.goffi.cagou
+
+# (str) Source code where the main.py live
+source.dir = .
+
+# (list) Source files to include (let empty to include all the files)
+source.include_exts = py,png,jpg,kv,atlas,conf
+# FIXME: check if we can do sat.conf only, without every .conf
+
+# (list) List of inclusions using pattern matching
+#source.include_patterns = assets/*,images/*.png
+source.include_patterns = media
+
+# (list) Source files to exclude (let empty to not exclude anything)
+#source.exclude_exts = spec
+
+# (list) List of directory to exclude (let empty to not exclude anything)
+#source.exclude_dirs = tests, bin
+
+# (list) List of exclusions using pattern matching
+#source.exclude_patterns = license,images/*/*.jpg
+
+# (str) Application versioning (method 1)
+version = 0.1
+
+# (str) Application versioning (method 2)
+# version.regex = __version__ = ['"](.*)['"]
+# version.filename = %(source.dir)s/main.py
+
+# (list) Application requirements
+# comma seperated e.g. requirements = sqlite3,kivy
+requirements = kivy, sqlite3, twisted, wokkel, pil, lxml, pyxdg, markdown, html2text, python-dateutil, pycrypto, pyopenssl
+
+# (str) Custom source folders for requirements
+# Sets custom source for any requirements with recipes
+# requirements.source.kivy = ../../kivy
+
+# (list) Garden requirements
+#garden_requirements =
+
+# (str) Presplash of the application
+#presplash.filename = %(source.dir)s/data/presplash.png
+
+# (str) Icon of the application
+#icon.filename = %(source.dir)s/data/icon.png
+
+# (str) Supported orientation (one of landscape, portrait or all)
+orientation = portrait
+
+# (list) List of service to declare
+#services = NAME:ENTRYPOINT_TO_PY,NAME2:ENTRYPOINT2_TO_PY
+
+#
+# OSX Specific
+#
+
+#
+# author = © Copyright Info
+
+#
+# Android specific
+#
+
+# (bool) Indicate if the application should be fullscreen or not
+fullscreen = 1
+
+# (list) Permissions
+android.permissions = INTERNET, ACCESS_NETWORK_STATE
+
+# (int) Android API to use
+#android.api = 19
+
+# (int) Minimum API required
+#android.minapi = 9
+
+# (int) Android SDK version to use
+#android.sdk = 20
+
+# (str) Android NDK version to use
+#android.ndk = 9c
+
+# (bool) Use --private data storage (True) or --dir public storage (False)
+#android.private_storage = True
+
+# (str) Android NDK directory (if empty, it will be automatically downloaded.)
+#android.ndk_path =
+
+# (str) Android SDK directory (if empty, it will be automatically downloaded.)
+#android.sdk_path =
+
+# (str) ANT directory (if empty, it will be automatically downloaded.)
+#android.ant_path =
+
+# (str) python-for-android git clone directory (if empty, it will be automatically cloned from github)
+# we use our own p4a and mount in root dir on docker image
+android.p4a_dir = /python-for-android-old
+
+# (str) The directory in which python-for-android should look for your own build recipes (if any)
+#p4a.local_recipes =
+
+# (list) python-for-android whitelist
+#android.p4a_whitelist =
+
+# (bool) If True, then skip trying to update the Android sdk
+# This can be useful to avoid excess Internet downloads or save time
+# when an update is due and you just want to test/build your package
+# android.skip_update = False
+
+# (str) Bootstrap to use for android builds (android_new only)
+# android.bootstrap = sdl2
+
+# (str) Android entry point, default is ok for Kivy-based app
+#android.entrypoint = org.renpy.android.PythonActivity
+
+# (list) List of Java .jar files to add to the libs so that pyjnius can access
+# their classes. Don't add jars that you do not need, since extra jars can slow
+# down the build process. Allows wildcards matching, for example:
+# OUYA-ODK/libs/*.jar
+#android.add_jars = foo.jar,bar.jar,path/to/more/*.jar
+
+# (list) List of Java files to add to the android project (can be java or a
+# directory containing the files)
+#android.add_src =
+
+# (str) python-for-android branch to use, if not master, useful to try
+# not yet merged features.
+#android.branch = master
+
+# (str) OUYA Console category. Should be one of GAME or APP
+# If you leave this blank, OUYA support will not be enabled
+#android.ouya.category = GAME
+
+# (str) Filename of OUYA Console icon. It must be a 732x412 png image.
+#android.ouya.icon.filename = %(source.dir)s/data/ouya_icon.png
+
+# (str) XML file to include as an intent filters in <activity> tag
+#android.manifest.intent_filters =
+
+# (list) Android additionnal libraries to copy into libs/armeabi
+#android.add_libs_armeabi = libs/android/*.so
+#android.add_libs_armeabi_v7a = libs/android-v7/*.so
+#android.add_libs_x86 = libs/android-x86/*.so
+#android.add_libs_mips = libs/android-mips/*.so
+
+# (bool) Indicate whether the screen should stay on
+# Don't forget to add the WAKE_LOCK permission if you set this to True
+#android.wakelock = False
+
+# (list) Android application meta-data to set (key=value format)
+#android.meta_data =
+
+# (list) Android library project to add (will be added in the
+# project.properties automatically.)
+#android.library_references =
+
+# (str) Android logcat filters to use
+#android.logcat_filters = *:S python:D
+
+# (bool) Copy library instead of making a libpymodules.so
+#android.copy_libs = 1
+
+#
+# iOS specific
+#
+
+# (str) Path to a custom kivy-ios folder
+#ios.kivy_ios_dir = ../kivy-ios
+
+# (str) Name of the certificate to use for signing the debug version
+# Get a list of available identities: buildozer ios list_identities
+#ios.codesign.debug = "iPhone Developer: <lastname> <firstname> (<hexstring>)"
+
+# (str) Name of the certificate to use for signing the release version
+#ios.codesign.release = %(ios.codesign.debug)s
+
+
+[buildozer]
+
+# (int) Log level (0 = error only, 1 = info, 2 = debug (with command output))
+log_level = 1
+
+# (int) Display warning if buildozer is run as root (0 = False, 1 = True)
+warn_on_root = 1
+
+# (str) Path to build artifact storage, absolute or relative to spec file
+# build_dir = ./.buildozer
+
+# (str) Path to build output (i.e. .apk, .ipa) storage
+# bin_dir = ./bin
+
+#    -----------------------------------------------------------------------------
+#    List as sections
+#
+#    You can define all the "list" as [section:key].
+#    Each line will be considered as a option to the list.
+#    Let's take [app] / source.exclude_patterns.
+#    Instead of doing:
+#
+#[app]
+#source.exclude_patterns = license,data/audio/*.wav,data/images/original/*
+#
+#    This can be translated into:
+#
+#[app:source.exclude_patterns]
+#license
+#data/audio/*.wav
+#data/images/original/*
+#
+
+
+#    -----------------------------------------------------------------------------
+#    Profiles
+#
+#    You can extend section / key with a profile
+#    For example, you want to deploy a demo version of your application without
+#    HD content. You could first change the title to add "(demo)" in the name
+#    and extend the excluded directories to remove the HD content.
+#
+#[app@demo]
+#title = My Application (demo)
+#
+#[app:source.exclude_patterns@demo]
+#images/hd/*
+#
+#    Then, invoke the command line with the "demo" profile:
+#
+#buildozer --profile demo android debug
--- a/src/cagou/core/cagou_main.py	Sun Dec 04 18:16:10 2016 +0100
+++ b/src/cagou/core/cagou_main.py	Sun Dec 04 18:21:23 2016 +0100
@@ -61,7 +61,14 @@
 import cagou.plugins
 import cagou.kv
 from sat.core import sat_main
+from kivy import utils as kivy_utils
 import sys
+if kivy_utils.platform == "android":
+    # FIXME: move to separate android module
+    kivy.support.install_android()
+    # sys.platform is "linux" on android by default
+    # so we change it to allow backend to detect android
+    sys.platform = "android"
 
 
 class NotifsIcon(IconButton):
@@ -266,6 +273,8 @@
         self.postInit()
 
     def postInit(self, dummy=None):
+        # FIXME: resize seem to bug on android, so we use below_target for now
+        self.app.root_window.softinput_mode = "below_target"
         profile_manager = self.app._profile_manager
         del self.app._profile_manager
         super(Cagou, self).postInit(profile_manager)
@@ -287,8 +296,15 @@
     def _import_plugins(self):
         """import all plugins"""
         self.default_wid = None
-        plugins_path = os.path.dirname(cagou.plugins.__file__)
-        plug_lst = [os.path.splitext(p)[0] for p in map(os.path.basename, glob.glob(os.path.join(plugins_path, "plugin*.py")))]
+        if sys.platform == "android":
+            # FIXME: android hack, need to be moved to separate file
+            plugins_path = "/data/data/org.goffi.cagou.cagou/files/cagou/plugins"
+            plugin_glob = "plugin*.pyo"
+        else:
+            plugins_path = os.path.dirname(cagou.plugins.__file__)
+            plugin_glob = "plugin*.py"
+        plug_lst = [os.path.splitext(p)[0] for p in map(os.path.basename, glob.glob(os.path.join(plugins_path, plugin_glob)))]
+
         imported_names = set()  # use to avoid loading 2 times plugin with same import name
         for plug in plug_lst:
             plugin_path = 'cagou.plugins.' + plug
@@ -492,3 +508,8 @@
 
     def getDefaultAvatar(self, entity=None):
         return self.app.default_avatar
+
+    def showDialog(self, message, title, type="info", answer_cb=None, answer_data=None):
+        # TODO
+        log.info(u"FIXME: showDialog not implemented")
+        log.info(u"message: {} -- {}".format(title, message))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/sat.conf	Sun Dec 04 18:21:23 2016 +0100
@@ -0,0 +1,8 @@
+[DEFAULT]
+bridge = embedded
+log_level = debug
+log_fmt = [%%(levelname)s][%%(name)s] %%(message)s
+
+[cagou]
+log_level = debug
+log_fmt = [%%(levelname)s][%%(name)s] %%(message)s