Merge branch 'overhaul-import' into 'master'

Overhaul `fdroid import`

See merge request fdroid/fdroidserver!714
This commit is contained in:
Hans-Christoph Steiner 2020-02-13 21:31:45 +00:00
commit 1408e486dc
29 changed files with 1302 additions and 122 deletions

View file

@ -18,21 +18,30 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import binascii import binascii
import glob
import json
import os import os
import re import re
import shutil import shutil
import urllib.parse
import urllib.request import urllib.request
import yaml
from argparse import ArgumentParser from argparse import ArgumentParser
from configparser import ConfigParser
import logging import logging
try:
from yaml import CSafeLoader as SafeLoader
except ImportError:
from yaml import SafeLoader
from . import _ from . import _
from . import common from . import common
from . import metadata from . import metadata
from .exception import FDroidException from .exception import FDroidException
SETTINGS_GRADLE = re.compile(r'settings\.gradle(?:\.kts)?')
SETTINGS_GRADLE = re.compile(r'''include\s+['"]:([^'"]*)['"]''') GRADLE_SUBPROJECT = re.compile(r'''['"]:([^'"]+)['"]''')
ANDROID_PLUGIN = re.compile(r'''\s*(:?apply plugin:|id)\(?\s*['"](android|com\.android\.application)['"]\s*\)?''')
# Get the repo type and address from the given web page. The page is scanned # Get the repo type and address from the given web page. The page is scanned
@ -88,110 +97,112 @@ config = None
options = None options = None
def get_metadata_from_url(app, url): def get_app_from_url(url):
"""Guess basic app metadata from the URL.
The URL must include a network hostname, unless it is an lp:,
file:, or git/ssh URL. This throws ValueError on bad URLs to
match urlparse().
"""
parsed = urllib.parse.urlparse(url)
invalid_url = False
if not parsed.scheme or not parsed.path:
invalid_url = True
app = metadata.App()
app.Repo = url
if url.startswith('git://') or url.startswith('git@'):
app.RepoType = 'git'
elif parsed.netloc == 'github.com':
app.RepoType = 'git'
app.SourceCode = url
app.IssueTracker = url + '/issues'
elif parsed.netloc == 'gitlab.com':
# git can be fussy with gitlab URLs unless they end in .git
if url.endswith('.git'):
url = url[:-4]
app.Repo = url + '.git'
app.RepoType = 'git'
app.SourceCode = url
app.IssueTracker = url + '/issues'
elif parsed.netloc == 'notabug.org':
if url.endswith('.git'):
url = url[:-4]
app.Repo = url + '.git'
app.RepoType = 'git'
app.SourceCode = url
app.IssueTracker = url + '/issues'
elif parsed.netloc == 'bitbucket.org':
if url.endswith('/'):
url = url[:-1]
app.SourceCode = url + '/src'
app.IssueTracker = url + '/issues'
# Figure out the repo type and adddress...
app.RepoType, app.Repo = getrepofrompage(url)
elif url.startswith('https://') and url.endswith('.git'):
app.RepoType = 'git'
if not parsed.netloc and parsed.scheme in ('git', 'http', 'https', 'ssh'):
invalid_url = True
if invalid_url:
raise ValueError(_('"{url}" is not a valid URL!'.format(url=url)))
if not app.RepoType:
raise FDroidException("Unable to determine vcs type. " + app.Repo)
return app
def clone_to_tmp_dir(app):
tmp_dir = 'tmp' tmp_dir = 'tmp'
if not os.path.isdir(tmp_dir): if not os.path.isdir(tmp_dir):
logging.info(_("Creating temporary directory")) logging.info(_("Creating temporary directory"))
os.makedirs(tmp_dir) os.makedirs(tmp_dir)
# Figure out what kind of project it is... tmp_dir = os.path.join(tmp_dir, 'importer')
projecttype = None if os.path.exists(tmp_dir):
app.WebSite = url # by default, we might override it shutil.rmtree(tmp_dir)
if url.startswith('git://'): vcs = common.getvcs(app.RepoType, app.Repo, tmp_dir)
projecttype = 'git'
repo = url
repotype = 'git'
app.SourceCode = ""
app.WebSite = ""
elif url.startswith('https://github.com'):
projecttype = 'github'
repo = url
repotype = 'git'
app.SourceCode = url
app.IssueTracker = url + '/issues'
app.WebSite = ""
elif url.startswith('https://gitlab.com/'):
projecttype = 'gitlab'
# git can be fussy with gitlab URLs unless they end in .git
if url.endswith('.git'):
url = url[:-4]
repo = url + '.git'
repotype = 'git'
app.WebSite = url
app.SourceCode = url + '/tree/HEAD'
app.IssueTracker = url + '/issues'
elif url.startswith('https://notabug.org/'):
projecttype = 'notabug'
if url.endswith('.git'):
url = url[:-4]
repo = url + '.git'
repotype = 'git'
app.SourceCode = url
app.IssueTracker = url + '/issues'
app.WebSite = ""
elif url.startswith('https://bitbucket.org/'):
if url.endswith('/'):
url = url[:-1]
projecttype = 'bitbucket'
app.SourceCode = url + '/src'
app.IssueTracker = url + '/issues'
# Figure out the repo type and adddress...
repotype, repo = getrepofrompage(url)
if not repotype:
raise FDroidException("Unable to determine vcs type. " + repo)
elif url.startswith('https://') and url.endswith('.git'):
projecttype = 'git'
repo = url
repotype = 'git'
app.SourceCode = ""
app.WebSite = ""
if not projecttype:
raise FDroidException("Unable to determine the project type. "
+ "The URL you supplied was not in one of the supported formats. "
+ "Please consult the manual for a list of supported formats, "
+ "and supply one of those.")
# Ensure we have a sensible-looking repo address at this point. If not, we
# might have got a page format we weren't expecting. (Note that we
# specifically don't want git@...)
if ((repotype != 'bzr' and (not repo.startswith('http://')
and not repo.startswith('https://')
and not repo.startswith('git://')))
or ' ' in repo):
raise FDroidException("Repo address '{0}' does not seem to be valid".format(repo))
# Get a copy of the source so we can extract some info...
logging.info('Getting source from ' + repotype + ' repo at ' + repo)
build_dir = os.path.join(tmp_dir, 'importer')
if os.path.exists(build_dir):
shutil.rmtree(build_dir)
vcs = common.getvcs(repotype, repo, build_dir)
vcs.gotorevision(options.rev) vcs.gotorevision(options.rev)
root_dir = get_subdir(build_dir)
app.RepoType = repotype return tmp_dir
app.Repo = repo
return root_dir, build_dir
config = None def get_all_gradle_and_manifests(build_dir):
options = None paths = []
for root, dirs, files in os.walk(build_dir):
for f in sorted(files):
if f == 'AndroidManifest.xml' \
or f.endswith('.gradle') or f.endswith('.gradle.kts'):
full = os.path.join(root, f)
paths.append(full)
return paths
def get_subdir(build_dir): def get_gradle_subdir(build_dir, paths):
if options.subdir: """get the subdir where the gradle build is based"""
return os.path.join(build_dir, options.subdir) first_gradle_dir = None
for path in paths:
if not first_gradle_dir:
first_gradle_dir = os.path.relpath(os.path.dirname(path), build_dir)
if os.path.exists(path) and SETTINGS_GRADLE.match(os.path.basename(path)):
with open(path) as fp:
for m in GRADLE_SUBPROJECT.finditer(fp.read()):
for f in glob.glob(os.path.join(os.path.dirname(path), m.group(1), 'build.gradle*')):
with open(f) as fp:
while True:
line = fp.readline()
if not line:
break
if ANDROID_PLUGIN.match(line):
return os.path.relpath(os.path.dirname(f), build_dir)
if first_gradle_dir and first_gradle_dir != '.':
return first_gradle_dir
settings_gradle = os.path.join(build_dir, 'settings.gradle') return ''
if os.path.exists(settings_gradle):
with open(settings_gradle) as fp:
m = SETTINGS_GRADLE.search(fp.read())
if m:
return os.path.join(build_dir, m.group(1))
return build_dir
def main(): def main():
@ -218,10 +229,8 @@ def main():
config = common.read_config(options) config = common.read_config(options)
apps = metadata.read_metadata() apps = metadata.read_metadata()
app = metadata.App() app = None
app.UpdateCheckMode = "Tags"
root_dir = None
build_dir = None build_dir = None
local_metadata_files = common.get_local_metadata_files() local_metadata_files = common.get_local_metadata_files()
@ -230,15 +239,16 @@ def main():
build = metadata.Build() build = metadata.Build()
if options.url is None and os.path.isdir('.git'): if options.url is None and os.path.isdir('.git'):
app = metadata.App()
app.AutoName = os.path.basename(os.getcwd()) app.AutoName = os.path.basename(os.getcwd())
app.RepoType = 'git' app.RepoType = 'git'
app.UpdateCheckMode = "Tags"
root_dir = get_subdir(os.getcwd())
if os.path.exists('build.gradle'): if os.path.exists('build.gradle'):
build.gradle = ['yes'] build.gradle = ['yes']
import git import git
repo = git.repo.Repo(root_dir) # git repo repo = git.repo.Repo(os.getcwd()) # git repo
for remote in git.Remote.iter_items(repo): for remote in git.Remote.iter_items(repo):
if remote.name == 'origin': if remote.name == 'origin':
url = repo.remotes.origin.url url = repo.remotes.origin.url
@ -250,7 +260,8 @@ def main():
build.commit = binascii.hexlify(bytearray(repo.head.commit.binsha)) build.commit = binascii.hexlify(bytearray(repo.head.commit.binsha))
write_local_file = True write_local_file = True
elif options.url: elif options.url:
root_dir, build_dir = get_metadata_from_url(app, options.url) app = get_app_from_url(options.url)
build_dir = clone_to_tmp_dir(app)
build.commit = '?' build.commit = '?'
build.disable = 'Generated by import.py - check/set version fields and commit id' build.disable = 'Generated by import.py - check/set version fields and commit id'
write_local_file = False write_local_file = False
@ -258,9 +269,9 @@ def main():
raise FDroidException("Specify project url.") raise FDroidException("Specify project url.")
# Extract some information... # Extract some information...
paths = common.manifest_paths(root_dir, []) paths = get_all_gradle_and_manifests(build_dir)
subdir = get_gradle_subdir(build_dir, paths)
if paths: if paths:
versionName, versionCode, package = common.parse_androidmanifests(paths, app) versionName, versionCode, package = common.parse_androidmanifests(paths, app)
if not package: if not package:
raise FDroidException(_("Couldn't find package ID")) raise FDroidException(_("Couldn't find package ID"))
@ -269,17 +280,7 @@ def main():
if not versionCode: if not versionCode:
logging.warn(_("Couldn't find latest version code")) logging.warn(_("Couldn't find latest version code"))
else: else:
spec = os.path.join(root_dir, 'buildozer.spec') raise FDroidException(_("No gradle project could be found. Specify --subdir?"))
if os.path.exists(spec):
defaults = {'orientation': 'landscape', 'icon': '',
'permissions': '', 'android.api': "18"}
bconfig = ConfigParser(defaults, allow_no_value=True)
bconfig.read(spec)
package = bconfig.get('app', 'package.domain') + '.' + bconfig.get('app', 'package.name')
versionName = bconfig.get('app', 'version')
versionCode = None
else:
raise FDroidException(_("No android or kivy project could be found. Specify --subdir?"))
# Make sure it's actually new... # Make sure it's actually new...
if package in apps: if package in apps:
@ -290,15 +291,48 @@ def main():
build.versionCode = versionCode or '0' # TODO heinous but this is still a str build.versionCode = versionCode or '0' # TODO heinous but this is still a str
if options.subdir: if options.subdir:
build.subdir = options.subdir build.subdir = options.subdir
elif subdir:
build.subdir = subdir
if options.license: if options.license:
app.License = options.license app.License = options.license
if options.categories: if options.categories:
app.Categories = options.categories.split(',') app.Categories = options.categories.split(',')
if os.path.exists(os.path.join(root_dir, 'jni')): if os.path.exists(os.path.join(subdir, 'jni')):
build.buildjni = ['yes'] build.buildjni = ['yes']
if os.path.exists(os.path.join(root_dir, 'build.gradle')): if os.path.exists(os.path.join(subdir, 'build.gradle')):
build.gradle = ['yes'] build.gradle = ['yes']
package_json = os.path.join(build_dir, 'package.json') # react-native
pubspec_yaml = os.path.join(build_dir, 'pubspec.yaml') # flutter
if os.path.exists(package_json):
build.sudo = ['apt-get install npm', 'npm install -g react-native-cli']
build.init = ['npm install']
with open(package_json) as fp:
data = json.load(fp)
app.AutoName = data.get('name', app.AutoName)
app.License = data.get('license', app.License)
app.Description = data.get('description', app.Description)
app.WebSite = data.get('homepage', app.WebSite)
app_json = os.path.join(build_dir, 'app.json')
if os.path.exists(app_json):
with open(app_json) as fp:
data = json.load(fp)
app.AutoName = data.get('name', app.AutoName)
if os.path.exists(pubspec_yaml):
with open(pubspec_yaml) as fp:
data = yaml.load(fp, Loader=SafeLoader)
app.AutoName = data.get('name', app.AutoName)
app.License = data.get('license', app.License)
app.Description = data.get('description', app.Description)
build.srclibs = ['flutter@stable']
build.output = 'build/app/outputs/apk/release/app-release.apk'
build.build = [
'$$flutter$$/bin/flutter config --no-analytics',
'$$flutter$$/bin/flutter packages pub get',
'$$flutter$$/bin/flutter build apk',
]
metadata.post_metadata_parse(app) metadata.post_metadata_parse(app)
app.builds.append(build) app.builds.append(build)

View file

@ -286,6 +286,8 @@ def main():
parser = ArgumentParser(usage="%(prog)s [options] [APPID[:VERCODE] [APPID[:VERCODE] ...]]") parser = ArgumentParser(usage="%(prog)s [options] [APPID[:VERCODE] [APPID[:VERCODE] ...]]")
common.setup_global_opts(parser) common.setup_global_opts(parser)
parser.add_argument("appid", nargs='*', help=_("applicationId with optional versionCode in the form APPID[:VERCODE]")) parser.add_argument("appid", nargs='*', help=_("applicationId with optional versionCode in the form APPID[:VERCODE]"))
parser.add_argument("-f", "--force", action="store_true", default=False,
help=_("Force scan of disabled apps and builds."))
metadata.add_metadata_arguments(parser) metadata.add_metadata_arguments(parser)
options = parser.parse_args() options = parser.parse_args()
metadata.warnings_action = options.W metadata.warnings_action = options.W
@ -307,7 +309,7 @@ def main():
for appid, app in apps.items(): for appid, app in apps.items():
if app.Disabled: if app.Disabled and not options.force:
logging.info(_("Skipping {appid}: disabled").format(appid=appid)) logging.info(_("Skipping {appid}: disabled").format(appid=appid))
continue continue
@ -334,7 +336,7 @@ def main():
for build in app.builds: for build in app.builds:
if build.disable: if build.disable and not options.force:
logging.info("...skipping version %s - %s" % ( logging.info("...skipping version %s - %s" % (
build.versionName, build.get('disable', build.commit[1:]))) build.versionName, build.get('disable', build.commit[1:])))
continue continue

View file

@ -816,6 +816,30 @@ class CommonTest(unittest.TestCase):
self.assertEqual(('0.94-test', '940', 'org.fdroid.fdroid'), self.assertEqual(('0.94-test', '940', 'org.fdroid.fdroid'),
fdroidserver.common.parse_androidmanifests(paths, app)) fdroidserver.common.parse_androidmanifests(paths, app))
app = fdroidserver.metadata.App()
app.AutoName = 'android-chat'
app.RepoType = 'git'
url = 'https://github.com/wildfirechat/android-chat.git'
app.SourceCode = url.rstrip('.git')
app.Repo = url
paths = [
os.path.join('source-files', 'cn.wildfirechat.chat', 'avenginekit', 'build.gradle'),
os.path.join('source-files', 'cn.wildfirechat.chat', 'build.gradle'),
os.path.join('source-files', 'cn.wildfirechat.chat', 'client', 'build.gradle'),
os.path.join('source-files', 'cn.wildfirechat.chat', 'client', 'src', 'main', 'AndroidManifest.xml'),
os.path.join('source-files', 'cn.wildfirechat.chat', 'emojilibrary', 'build.gradle'),
os.path.join('source-files', 'cn.wildfirechat.chat', 'gradle', 'build_libraries.gradle'),
os.path.join('source-files', 'cn.wildfirechat.chat', 'imagepicker', 'build.gradle'),
os.path.join('source-files', 'cn.wildfirechat.chat', 'mars-core-release', 'build.gradle'),
os.path.join('source-files', 'cn.wildfirechat.chat', 'push', 'build.gradle'),
os.path.join('source-files', 'cn.wildfirechat.chat', 'settings.gradle'),
os.path.join('source-files', 'cn.wildfirechat.chat', 'chat', 'build.gradle'),
]
for path in paths:
self.assertTrue(os.path.isfile(path))
self.assertEqual(('0.6.9', '23', 'cn.wildfirechat.chat'),
fdroidserver.common.parse_androidmanifests(paths, app))
def test_parse_androidmanifests_ignore(self): def test_parse_androidmanifests_ignore(self):
app = fdroidserver.metadata.App() app = fdroidserver.metadata.App()
app.id = 'org.fdroid.fdroid' app.id = 'org.fdroid.fdroid'

View file

@ -7,8 +7,11 @@ import logging
import optparse import optparse
import os import os
import requests import requests
import shutil
import sys import sys
import tempfile
import unittest import unittest
from unittest import mock
localmodule = os.path.realpath( localmodule = os.path.realpath(
os.path.join(os.path.dirname(inspect.getfile(inspect.currentframe())), '..')) os.path.join(os.path.dirname(inspect.getfile(inspect.currentframe())), '..'))
@ -46,13 +49,86 @@ class ImportTest(unittest.TestCase):
print('Skipping ImportTest!') print('Skipping ImportTest!')
return return
app = fdroidserver.metadata.App() app = import_proxy.get_app_from_url(url)
app.UpdateCheckMode = "Tags" import_proxy.clone_to_tmp_dir(app)
root_dir, src_dir = import_proxy.get_metadata_from_url(app, url)
self.assertEqual(app.RepoType, 'git') self.assertEqual(app.RepoType, 'git')
self.assertEqual(app.WebSite, 'https://gitlab.com/fdroid/ci-test-app')
self.assertEqual(app.Repo, 'https://gitlab.com/fdroid/ci-test-app.git') self.assertEqual(app.Repo, 'https://gitlab.com/fdroid/ci-test-app.git')
def test_get_all_gradle_and_manifests(self):
a = import_proxy.get_all_gradle_and_manifests(os.path.join('source-files', 'cn.wildfirechat.chat'))
paths = [
os.path.join('source-files', 'cn.wildfirechat.chat', 'avenginekit', 'build.gradle'),
os.path.join('source-files', 'cn.wildfirechat.chat', 'build.gradle'),
os.path.join('source-files', 'cn.wildfirechat.chat', 'chat', 'build.gradle'),
os.path.join('source-files', 'cn.wildfirechat.chat', 'client', 'build.gradle'),
os.path.join('source-files', 'cn.wildfirechat.chat', 'client', 'src', 'main', 'AndroidManifest.xml'),
os.path.join('source-files', 'cn.wildfirechat.chat', 'emojilibrary', 'build.gradle'),
os.path.join('source-files', 'cn.wildfirechat.chat', 'gradle', 'build_libraries.gradle'),
os.path.join('source-files', 'cn.wildfirechat.chat', 'imagepicker', 'build.gradle'),
os.path.join('source-files', 'cn.wildfirechat.chat', 'mars-core-release', 'build.gradle'),
os.path.join('source-files', 'cn.wildfirechat.chat', 'push', 'build.gradle'),
os.path.join('source-files', 'cn.wildfirechat.chat', 'settings.gradle'),
]
self.assertEqual(sorted(paths), sorted(a))
def test_get_gradle_subdir(self):
subdirs = {
'cn.wildfirechat.chat': 'chat',
'com.anpmech.launcher': 'app',
'org.tasks': 'app',
'ut.ewh.audiometrytest': 'app',
}
for f in ('cn.wildfirechat.chat', 'com.anpmech.launcher', 'org.tasks', 'ut.ewh.audiometrytest'):
build_dir = os.path.join('source-files', f)
paths = import_proxy.get_all_gradle_and_manifests(build_dir)
logging.info(paths)
subdir = import_proxy.get_gradle_subdir(build_dir, paths)
self.assertEqual(subdirs[f], subdir)
def test_bad_urls(self):
for url in ('asdf',
'file://thing.git',
'https:///github.com/my/project',
'git:///so/many/slashes',
'ssh:/notabug.org/missing/a/slash',
'git:notabug.org/missing/some/slashes',
'https//github.com/bar/baz'):
with self.assertRaises(ValueError):
import_proxy.get_app_from_url(url)
def test_get_app_from_url(self):
testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir)
os.chdir(testdir)
os.mkdir(os.path.join(testdir, 'tmp'))
tmp_importer = os.path.join(testdir, 'tmp', 'importer')
data = (
('cn.wildfirechat.chat', 'https://github.com/wildfirechat/android-chat', '0.6.9', '23'),
('com.anpmech.launcher', 'https://github.com/KeikaiLauncher/KeikaiLauncher', 'Unknown', None),
('ut.ewh.audiometrytest', 'https://github.com/ReeceStevens/ut_ewh_audiometer_2014', '1.65', '14'),
)
for appid, url, vn, vc in data:
shutil.rmtree(tmp_importer, ignore_errors=True)
shutil.copytree(os.path.join(self.basedir, 'source-files', appid),
tmp_importer)
app = import_proxy.get_app_from_url(url)
with mock.patch('fdroidserver.common.getvcs',
lambda a, b, c: fdroidserver.common.vcs(url, testdir)):
with mock.patch('fdroidserver.common.vcs.gotorevision',
lambda s, rev: None):
with mock.patch('shutil.rmtree', lambda a: None):
build_dir = import_proxy.clone_to_tmp_dir(app)
self.assertEqual('git', app.RepoType)
self.assertEqual(url, app.Repo)
self.assertEqual(url, app.SourceCode)
logging.info(build_dir)
paths = import_proxy.get_all_gradle_and_manifests(build_dir)
self.assertNotEqual(paths, [])
versionName, versionCode, package = fdroidserver.common.parse_androidmanifests(paths, app)
self.assertEqual(vn, versionName)
self.assertEqual(vc, versionCode)
self.assertEqual(appid, package)
if __name__ == "__main__": if __name__ == "__main__":
os.chdir(os.path.dirname(__file__)) os.chdir(os.path.dirname(__file__))

View file

@ -18,7 +18,10 @@ class Options:
module = __import__('fdroidserver.import') module = __import__('fdroidserver.import')
for name, obj in inspect.getmembers(module): for name, obj in inspect.getmembers(module):
if name == 'import': if name == 'import':
get_metadata_from_url = obj.get_metadata_from_url clone_to_tmp_dir = obj.clone_to_tmp_dir
get_all_gradle_and_manifests = obj.get_all_gradle_and_manifests
get_app_from_url = obj.get_app_from_url
get_gradle_subdir = obj.get_gradle_subdir
obj.options = Options() obj.options = Options()
options = obj.options options = obj.options
break break

View file

@ -28,6 +28,7 @@ class ScannerTest(unittest.TestCase):
def test_scan_source_files(self): def test_scan_source_files(self):
source_files = os.path.join(self.basedir, 'source-files') source_files = os.path.join(self.basedir, 'source-files')
projects = { projects = {
'cn.wildfirechat.chat': 4,
'Zillode': 1, 'Zillode': 1,
'firebase-suspect': 1, 'firebase-suspect': 1,
'org.mozilla.rocket': 3, 'org.mozilla.rocket': 3,

View file

@ -0,0 +1,2 @@
configurations.maybeCreate("default")
artifacts.add("default", file('avenginekit.aar'))

View file

@ -0,0 +1,41 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
jcenter()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.4.2'
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
maven {
url "http://developer.huawei.com/repo/"
}
maven { url 'https://jitpack.io' }
maven { url 'https://dl.bintray.com/jenly/maven' }
}
configurations {
all {
resolutionStrategy {
//force "android.arch.lifecycle:runtime:1.1.1"
}
}
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}

View file

@ -0,0 +1,115 @@
apply plugin: 'com.android.application'
android {
signingConfigs {
wfc {
keyAlias 'wfc'
keyPassword 'wildfirechat'
storeFile file('../wfc.keystore')
storePassword 'wildfirechat'
}
}
compileSdkVersion 28
aaptOptions.cruncherEnabled = false
aaptOptions.useNewCruncher = false
defaultConfig {
applicationId "cn.wildfirechat.chat"
minSdkVersion 16
targetSdkVersion 28 //targetversion大于23时使fileprovider
versionCode 23
versionName "0.6.9"
multiDexEnabled true
javaCompileOptions {
annotationProcessorOptions {
includeCompileClasspath true
}
}
signingConfig signingConfigs.wfc
// buildConfigField("String", "BuglyId", '"34490ba79f"')
ndk {
abiFilters "armeabi-v7a", 'x86', 'x86_64' // 'armeabi', 'arm64-v8a', 'x86', 'x86_64'
}
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.wfc
}
debug {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.wfc
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
lintOptions {
abortOnError false
}
sourceSets {
main {
// wfc kit start
jniLibs.srcDirs += ['libs', 'kit/libs']
res.srcDirs += ['kit/src/main/res', 'kit/src/main/res-av']
assets.srcDirs += ['kit/src/main/assets']
java.srcDirs += ['kit/src/main/java']
// wfc kit end
}
}
productFlavors {
}
compileOptions {
sourceCompatibility 1.8
targetCompatibility 1.8
}
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation files('libs/TencentLocationSDK_v4.9.7.12_r247861_161205_1104.jar')
implementation files('libs/TencentMapSDK_Raster_v_1.2.7_51ae0e7.jar')
implementation files('libs/TencentSearch1.1.3.jar')
implementation 'com.tencent.bugly:crashreport:2.8.6.0'
implementation 'com.tencent.bugly:nativecrashreport:3.6.0.1'
implementation 'com.lqr.adapter:library:1.0.2'
implementation 'com.jaeger.statusbaruitl:library:1.3.5'
implementation project(':push')
// wfc kit start
implementation fileTree(include: ['*.jar'], dir: 'kit/libs')
implementation 'androidx.appcompat:appcompat:1.1.0-beta01'
implementation 'com.google.android.material:material:1.1.0-alpha10'
implementation 'cjt.library.wheel:camera:1.1.9'
implementation 'com.kyleduo.switchbutton:library:1.4.4'
implementation 'com.squareup.okhttp3:okhttp:3.11.0'
implementation 'com.squareup.okio:okio:1.14.0'
implementation 'com.jakewharton:butterknife:10.2.0'
annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.0'
implementation 'com.github.bumptech.glide:glide:4.8.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.8.0'
implementation 'com.github.chrisbanes:PhotoView:2.3.0'
implementation 'org.webrtc:google-webrtc:1.0.21929'
implementation 'com.afollestad.material-dialogs:core:0.9.6.0'
implementation 'q.rorbin:badgeview:1.1.3'
implementation 'com.google.code.gson:gson:2.8.5'
// ViewModel and LiveData
def lifecycle_version = '2.2.0-alpha05'
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
implementation project(':client')
implementation project(':avenginekit')
implementation project(':emojilibrary')
implementation project(':imagepicker')
implementation 'com.king.zxing:zxing-lite:1.1.1'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.0.0'
// kit wfc end
}

View file

@ -0,0 +1,57 @@
apply plugin: 'com.android.library'
apply plugin: 'com.github.dcendents.android-maven'
group = 'com.github.wildfirechat'
android {
compileSdkVersion 28
defaultConfig {
minSdkVersion 16
targetSdkVersion 28
versionCode 1
versionName "1.0"
// testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
ndk {
// TODO: changes this for your application if needed
moduleName = "mmnet"
//abiFilter "armeabi" //armeabi架构armeabi-v7a可以兼容armeabi架构
abiFilter "armeabi-v7a"
abiFilter "arm64-v8a"
abiFilter "x86"
abiFilter "x86_64"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
lintOptions {
abortOnError false
}
compileOptions {
targetCompatibility 1.8
sourceCompatibility 1.8
}
}
dependencies {
api project(':mars-core-release')
def lifecycle_version = '2.0.0-beta01'
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
}

View file

@ -0,0 +1,26 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="cn.wildfirechat.client">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<application>
<service
android:name="cn.wildfirechat.client.ClientService"
android:process=":marsservice" />
<receiver
android:name="com.tencent.mars.BaseEvent$ConnectionReceiver"
android:process=":marsservice" />
<!--must run in th main process-->
<receiver android:name="cn.wildfirechat.remote.RecoverReceiver" />
</application>
</manifest>

View file

@ -0,0 +1,34 @@
apply plugin: 'com.android.library'
android {
compileSdkVersion 28
defaultConfig {
minSdkVersion 16
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
android {
lintOptions {
abortOnError false
}
}
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'androidx.appcompat:appcompat:1.0.0-beta01'
}

View file

@ -0,0 +1,42 @@
def checkExecResult(execResult) {
if (execResult) {
if (execResult.getExitValue() != 0) {
throw new GradleException('Non-zero exit value: ' + execResult.getExitValue())
}
} else {
throw new GradleException('Returned a null execResult object')
}
}
task buildLibrariesForAndroid(type: Exec) {
workingDir '../'
def sdkDir = System.env.ANDROID_HOME
def ndkDir = System.env.ANDROID_NDK_HOME
if (rootProject.file("local.properties").exists()) {
Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
sdkDir = properties.getProperty('sdk.dir')
ndkDir = properties.getProperty('ndk.dir')
}
def path = System.env.PATH
def envMap = [
'ANDROID_HOME' : sdkDir,
'ANDROID_NDK_HOME': ndkDir,
'_ARCH_' : 'armeabi',
'PATH' : ndkDir,
]
environment envMap
print envMap
commandLine 'python', 'build_android.py', '2', 'armeabi'
doLast {
checkExecResult(execResult)
}
}

View file

@ -0,0 +1,30 @@
apply plugin: 'com.android.library'
android {
compileSdkVersion 28
defaultConfig {
minSdkVersion 16
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
lintOptions {
abortOnError false
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.0.0-beta01'
implementation 'com.github.chrisbanes.photoview:library:1.2.4'
implementation 'com.github.bumptech.glide:glide:4.8.0'
}

View file

@ -0,0 +1,2 @@
configurations.maybeCreate("default")
artifacts.add("default", file('mars-core-release.aar'))

View file

@ -0,0 +1,55 @@
apply plugin: 'com.android.library'
android {
compileSdkVersion 28
defaultConfig {
minSdkVersion 16
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
manifestPlaceholders = [
MI_APP_ID : "2882303761517722456",
MI_APP_KEY : "5731772292456",
HMS_APP_ID : "100221325",
MEIZU_APP_ID : "113616",
MEIZU_APP_KEY: "fcd886f51c144b45b87a67a28e2934d1",
VIVO_APP_ID : "12918",
VIVO_APP_KEY : "c42feb05-de6c-427d-af55-4f902d9e0a75"
]
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility 1.8
targetCompatibility 1.8
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.huawei.android.hms:push:2.5.3.305'
implementation 'com.huawei.android.hms:base:2.5.3.305'
implementation 'androidx.appcompat:appcompat:1.0.0-beta01'
implementation project(':client')
implementation 'com.meizu.flyme.internet:push-internal:3.4.2@aar'
def lifecycle_version = '2.2.0-alpha05'
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
}

View file

@ -0,0 +1,7 @@
include ':client',
':push',
':chat',
':mars-core-release',
':emojilibrary',
':imagepicker',
':avenginekit'

View file

@ -0,0 +1,76 @@
/*
* Copyright 2015-2017 Hayai Software
* Copyright 2018 The KeikaiLauncher Project
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND
* either express or implied. See the License for the specific language governing permissions and
* limitations under the License.
*/
plugins {
id 'com.android.application'
id 'pl.allegro.tech.build.axion-release' version '1.8.1'
}
scmVersion {
tag {
prefix = ''
}
}
/**
* Takes version {@code major.minor.patch[-suffix]} and returns numeric versionCode based on it
* Example: {@code 1.2.3-SNAPSHOT} will return {@code 1002003}
*/
static int versionCode(String versionName) {
def matcher = (versionName =~ /(\d+)\.(\d+)\.(\d+).*/)
return matcher.matches() ?
matcher.collect { version, major, minor, patch ->
major.toInteger() * 10000 + minor.toInteger() * 100 + patch.toInteger()
}.head() :
-1
}
def androidVersion = [
name: scmVersion.version,
code: versionCode(scmVersion.version),
]
android {
compileSdkVersion 28
defaultConfig {
applicationId 'com.anpmech.launcher'
minSdkVersion 15
targetSdkVersion 28
versionName androidVersion.name
versionCode androidVersion.code
}
lintOptions {
abortOnError false
}
buildTypes {
all {
buildConfigField("String", "GITHUB_USER", "\"KeikaiLauncher\"")
buildConfigField("String", "GITHUB_PROJECT", "\"KeikaiLauncher\"")
}
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.txt'
}
debug {
versionNameSuffix "-debug"
}
}
dependencies {
implementation 'com.android.support:support-annotations:28.0.0'
}
}
dependencies {
}

View file

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright 2015-2017 Hayai Software
~ Copyright 2018 The KeikaiLauncher Project
~
~ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
~ in compliance with the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software distributed under the
~ License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND
~ either express or implied. See the License for the specific language governing permissions and
~ limitations under the License.
-->
<manifest package="com.anpmech.launcher"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<!--
~ This permission completely optional and set in the system settings menus. The following
~ declares intention to use, if available and granted.
-->
<uses-permission
android:name="android.permission.PACKAGE_USAGE_STATS"
tools:ignore="ProtectedPermissions"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:resizeableActivity="true"
android:theme="@style/AppBaseTheme"
tools:ignore="AllowBackup,GoogleAppIndexingWarning"
tools:targetApi="n">
<activity
android:name="com.anpmech.launcher.activities.SearchActivity"
android:alwaysRetainTaskState="true"
android:label="@string/title_activity_search"
android:launchMode="singleTask"
android:windowSoftInputMode="stateHidden|adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<action android:name="android.intent.action.ASSIST"/>
<category android:name="android.intent.category.LAUNCHER"/>
<category android:name="android.intent.category.HOME"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<activity
android:name="com.anpmech.launcher.activities.SettingsActivity"
android:label="@string/title_activity_settings"
android:theme="@style/AppSettingsTheme"/>
<activity
android:name=".activities.AboutActivity"
android:label="@string/about_header"
android:theme="@android:style/Theme.DeviceDefault.Light.Dialog"/>
<receiver
android:name=".monitor.PackageChangedReceiver"
android:enabled="false"/>
</application>
</manifest>

View file

@ -0,0 +1,45 @@
/*
* Copyright 2015-2017 Hayai Software
* Copyright 2018 The KeikaiLauncher Project
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND
* either express or implied. See the License for the specific language governing permissions and
* limitations under the License.
*/
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
}
}
allprojects {
repositories {
jcenter()
google()
}
}
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'org.owasp:dependency-check-gradle:5.2.4'
}
}
apply plugin: 'org.owasp.dependencycheck'
dependencyCheck {
format='JSON'
}

View file

@ -0,0 +1,16 @@
/*
* Copyright 2015-2017 Hayai Software
* Copyright 2018 The KeikaiLauncher Project
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND
* either express or implied. See the License for the specific language governing permissions and
* limitations under the License.
*/
include ':app'

View file

@ -0,0 +1,225 @@
import com.android.build.gradle.api.ApplicationVariant
plugins {
id("com.android.application")
id("checkstyle")
id("io.fabric")
id("com.cookpad.android.licensetools")
kotlin("android")
}
repositories {
jcenter()
google()
maven(url = "https://jitpack.io")
}
android {
bundle {
language {
enableSplit = false
}
}
dexOptions {
javaMaxHeapSize = "2g"
}
lintOptions {
setLintConfig(file("lint.xml"))
textOutput("stdout")
textReport = true
}
compileSdkVersion(Versions.targetSdk)
defaultConfig {
testApplicationId = "org.tasks.test"
applicationId = "org.tasks"
versionCode = 651
versionName = "7.6.1"
targetSdkVersion(Versions.targetSdk)
minSdkVersion(Versions.minSdk)
multiDexEnabled = true
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
javaCompileOptions {
annotationProcessorOptions {
arguments["room.schemaLocation"] = "$projectDir/schemas"
}
}
}
signingConfigs {
create("release") {
val tasksKeyAlias: String? by project
val tasksStoreFile: String? by project
val tasksStorePassword: String? by project
val tasksKeyPassword: String? by project
keyAlias = tasksKeyAlias
storeFile = file(tasksStoreFile?: "none")
storePassword = tasksStorePassword
keyPassword = tasksKeyPassword
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
@Suppress("LocalVariableName")
buildTypes {
getByName("debug") {
val tasks_mapbox_key_debug: String? by project
val tasks_google_key_debug: String? by project
applicationIdSuffix = ".debug"
resValue("string", "mapbox_key", tasks_mapbox_key_debug ?: "")
resValue("string", "google_key", tasks_google_key_debug ?: "")
isTestCoverageEnabled = true
}
getByName("release") {
val tasks_mapbox_key: String? by project
val tasks_google_key: String? by project
resValue("string", "mapbox_key", tasks_mapbox_key ?: "")
resValue("string", "google_key", tasks_google_key ?: "")
isMinifyEnabled = true
proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard.pro")
signingConfig = signingConfigs.getByName("release")
}
}
applicationVariants.all(object : Action<ApplicationVariant> {
override fun execute(variant: ApplicationVariant) {
variant.resValue("string", "app_package", variant.applicationId)
}
})
flavorDimensions("store")
productFlavors {
create("generic") {
setDimension("store")
proguardFile("generic.pro")
}
create("googleplay") {
setDimension("store")
}
create("amazon") {
setDimension("store")
}
}
viewBinding {
isEnabled = true
}
dataBinding {
isEnabled = true
}
packagingOptions {
exclude("META-INF/*.kotlin_module")
}
}
configure<CheckstyleExtension> {
configFile = project.file("google_checks.xml")
toolVersion = "8.16"
}
configurations.all {
exclude(group = "com.google.guava", module = "guava-jdk5")
exclude(group = "org.apache.httpcomponents", module = "httpclient")
exclude(group = "com.google.http-client", module = "google-http-client-apache")
resolutionStrategy {
force("com.squareup.okhttp3:okhttp:" + Versions.okhttp)
}
}
val googleplayImplementation by configurations
val amazonImplementation by configurations
dependencies {
implementation("com.gitlab.bitfireAT:dav4jvm:1.0")
implementation("com.gitlab.bitfireAT:ical4android:be6d515db8") {
exclude(group = "org.threeten", module = "threetenbp")
}
implementation("com.gitlab.bitfireAT:cert4android:1488e39a66")
annotationProcessor("com.google.dagger:dagger-compiler:${Versions.dagger}")
implementation("com.google.dagger:dagger:${Versions.dagger}")
implementation("androidx.room:room-rxjava2:${Versions.room}")
annotationProcessor("androidx.room:room-compiler:${Versions.room}")
implementation("androidx.lifecycle:lifecycle-extensions:2.1.0")
implementation("io.reactivex.rxjava2:rxandroid:2.1.1")
implementation("androidx.paging:paging-runtime:2.1.1")
annotationProcessor("com.jakewharton:butterknife-compiler:${Versions.butterknife}")
implementation("com.jakewharton:butterknife:${Versions.butterknife}")
debugImplementation("com.facebook.flipper:flipper:${Versions.flipper}")
debugImplementation("com.facebook.flipper:flipper-network-plugin:${Versions.flipper}")
debugImplementation("com.facebook.soloader:soloader:0.8.0")
debugImplementation("com.squareup.leakcanary:leakcanary-android:${Versions.leakcanary}")
implementation("org.jetbrains.kotlin:kotlin-stdlib:${Versions.kotlin}")
implementation("io.github.luizgrp.sectionedrecyclerviewadapter:sectionedrecyclerviewadapter:2.0.0")
implementation("androidx.multidex:multidex:2.0.1")
implementation("me.saket:better-link-movement-method:2.2.0")
implementation("com.squareup.okhttp3:okhttp:${Versions.okhttp}")
implementation("com.google.code.gson:gson:2.8.5")
implementation("com.github.rey5137:material:1.2.5")
implementation("com.nononsenseapps:filepicker:4.2.1")
implementation("com.google.android.material:material:1.1.0-rc01")
implementation("androidx.annotation:annotation:1.1.0")
implementation("androidx.constraintlayout:constraintlayout:2.0.0-beta4")
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.0.0")
implementation("com.jakewharton.timber:timber:4.7.1")
implementation("com.jakewharton.threetenabp:threetenabp:1.2.1")
implementation("com.google.guava:guava:27.1-android")
implementation("com.jakewharton:process-phoenix:2.0.0")
implementation("com.google.android.apps.dashclock:dashclock-api:2.0.0")
implementation("com.twofortyfouram:android-plugin-api-for-locale:1.0.2")
implementation("com.rubiconproject.oss:jchronic:0.2.6") {
isTransitive = false
}
implementation("org.scala-saddle:google-rfc-2445:20110304") {
isTransitive = false
}
implementation("com.wdullaer:materialdatetimepicker:4.0.1")
implementation("me.leolin:ShortcutBadger:1.1.22@aar")
implementation("com.google.apis:google-api-services-tasks:v1-rev59-1.25.0")
implementation("com.google.apis:google-api-services-drive:v3-rev188-1.25.0")
implementation("com.google.api-client:google-api-client-android:1.30.7")
implementation("androidx.work:work-runtime:${Versions.work}")
implementation("com.mapbox.mapboxsdk:mapbox-android-sdk:7.3.0")
implementation("com.mapbox.mapboxsdk:mapbox-sdk-services:4.6.0")
googleplayImplementation("com.crashlytics.sdk.android:crashlytics:${Versions.crashlytics}")
googleplayImplementation("com.google.firebase:firebase-analytics:${Versions.firebase}")
googleplayImplementation("com.google.android.gms:play-services-location:17.0.0")
googleplayImplementation("com.google.android.gms:play-services-maps:17.0.0")
googleplayImplementation("com.google.android.libraries.places:places:2.1.0")
googleplayImplementation("com.android.billingclient:billing:1.2.2")
amazonImplementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
amazonImplementation("com.crashlytics.sdk.android:crashlytics:${Versions.crashlytics}")
amazonImplementation("com.google.firebase:firebase-core:${Versions.firebase}")
androidTestAnnotationProcessor("com.google.dagger:dagger-compiler:${Versions.dagger}")
androidTestAnnotationProcessor("com.jakewharton:butterknife-compiler:${Versions.butterknife}")
androidTestImplementation("com.google.dexmaker:dexmaker-mockito:1.2")
androidTestImplementation("com.natpryce:make-it-easy:4.0.1")
androidTestImplementation("androidx.test:runner:1.2.0")
androidTestImplementation("androidx.test:rules:1.2.0")
androidTestImplementation("androidx.test.ext:junit:1.1.1")
androidTestImplementation("androidx.annotation:annotation:1.1.0")
}
apply(mapOf("plugin" to "com.google.gms.google-services"))

View file

@ -0,0 +1,13 @@
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'org.owasp:dependency-check-gradle:1.3.2.1'
}
}
apply plugin: 'org.owasp.dependencycheck'
dependencyCheck {
format='JSON'
}

View file

@ -0,0 +1,26 @@
buildscript {
repositories {
jcenter()
google()
maven("https://maven.fabric.io/public")
}
dependencies {
classpath("com.android.tools.build:gradle:3.6.0-rc01")
classpath("com.google.gms:google-services:4.3.3")
// https://docs.fabric.io/android/changelog.html#fabric-gradle-plugin
classpath("io.fabric.tools:gradle:1.31.2")
classpath("com.github.ben-manes:gradle-versions-plugin:0.27.0")
classpath("com.cookpad.android.licensetools:license-tools-plugin:1.7.0")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${Versions.kotlin}")
}
}
plugins {
id("com.github.ben-manes.versions") version "0.21.0"
}
tasks.getByName<Wrapper>("wrapper") {
gradleVersion = "5.6.4"
distributionType = Wrapper.DistributionType.ALL
}

View file

@ -0,0 +1,7 @@
plugins {
`kotlin-dsl`
}
repositories {
jcenter()
}

View file

@ -0,0 +1 @@
include(":app")

View file

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="ut.ewh.audiometrytest"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="ut.ewh.audiometrytest.MainActivity"
android:label="@string/app_name"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="ut.ewh.audiometrytest.PreTestInformation"
android:label="@string/title_activity_pre_test_information"
android:screenOrientation="portrait"
android:parentActivityName="ut.ewh.audiometrytest.MainActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="ut.ewh.audiometrytest.MainActivity" />
</activity>
<activity
android:name="ut.ewh.audiometrytest.TestProctoring"
android:label="@string/title_activity_test_proctoring"
android:screenOrientation="portrait" >
</activity>
<activity
android:name="ut.ewh.audiometrytest.TestComplete"
android:label="@string/title_activity_test_complete"
android:screenOrientation="portrait"
android:parentActivityName="ut.ewh.audiometrytest.MainActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="ut.ewh.audiometrytest.MainActivity" />
</activity>
<activity
android:name="ut.ewh.audiometrytest.ExportData"
android:label="@string/title_activity_export_data"
android:parentActivityName="ut.ewh.audiometrytest.MainActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="ut.ewh.audiometrytest.MainActivity" />
</activity>
<activity
android:name="ut.ewh.audiometrytest.Pre_Calibration"
android:label="@string/title_activity_pre__calibration"
android:screenOrientation="portrait"
android:parentActivityName="ut.ewh.audiometrytest.MainActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="ut.ewh.audiometrytest.MainActivity" />
</activity>
<activity
android:name="ut.ewh.audiometrytest.Calibration"
android:label="@string/title_activity_calibration"
android:screenOrientation="portrait" >
</activity>
<activity
android:name="ut.ewh.audiometrytest.ExportComplete"
android:label="@string/title_activity_export_complete"
android:screenOrientation="portrait"
android:parentActivityName="ut.ewh.audiometrytest.ExportData" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="ut.ewh.audiometrytest.ExportData" />
</activity>
<activity
android:name="ut.ewh.audiometrytest.CalibrationComplete"
android:label="@string/title_activity_calibration_complete"
android:screenOrientation="portrait"
android:parentActivityName="ut.ewh.audiometrytest.Pre_Calibration" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="ut.ewh.audiometrytest.Pre_Calibration" />
</activity>
<activity
android:name="ut.ewh.audiometrytest.Acknowledgements"
android:label="@string/title_activity_acknowledgements"
android:screenOrientation="portrait"
android:parentActivityName="ut.ewh.audiometrytest.MainActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="ut.ewh.audiometrytest.MainActivity" />
</activity>
<activity
android:name="ut.ewh.audiometrytest.ExportError"
android:label="@string/title_activity_export_error"
android:parentActivityName="ut.ewh.audiometrytest.ExportData" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="ut.ewh.audiometrytest.ExportData" />
</activity>
<activity
android:name="ut.ewh.audiometrytest.TestLookup"
android:label="@string/title_activity_test_lookup"
android:parentActivityName="ut.ewh.audiometrytest.MainActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="MainActivity" />
</activity>
<activity
android:name="ut.ewh.audiometrytest.TestData"
android:label="@string/title_activity_test_data"
android:parentActivityName="ut.ewh.audiometrytest.TestLookup">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="TestLookup" />
</activity>
</application>
</manifest>

View file

@ -0,0 +1,29 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.0.0-rc4'
}
}
allprojects {
repositories {
mavenCentral()
}
}
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'org.owasp:dependency-check-gradle:1.3.2.1'
}
}
apply plugin: 'org.owasp.dependencycheck'
dependencyCheck {
format='JSON'
}

View file

@ -0,0 +1 @@
include ':app'