diff --git a/app/build.gradle b/app/build.gradle index 5e119e9b23..d05cb2f0f6 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,5 +1,4 @@ import org.apache.tools.ant.filters.ReplaceTokens -import com.android.builder.core.DefaultManifestParser //////////// // README // @@ -22,7 +21,7 @@ repositories { flatDir { dirs 'libs' } - maven { url "https://jitpack.io" } + maven { url 'https://jitpack.io' } } configurations { @@ -42,8 +41,8 @@ dependencies { testImplementation 'androidx.work:work-testing:2.7.1' testImplementation 'androidx.test.espresso:espresso-core:3.4.0' testImplementation 'androidx.test.espresso:espresso-intents:3.5.1' - testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.3.2" - testImplementation "io.mockk:mockk:1.12.7" + testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.3.2' + testImplementation 'io.mockk:mockk:1.12.7' testImplementation 'org.json:json:20140107' testImplementation project(path: ':commcare-core', configuration: 'testsAsJar') @@ -82,7 +81,7 @@ dependencies { implementation 'com.google.android.gms:play-services-maps:17.0.0' implementation 'joda-time:joda-time:2.9.4' implementation 'net.zetetic:android-database-sqlcipher:4.5.3@aar' - implementation "androidx.sqlite:sqlite:2.2.0" + implementation 'androidx.sqlite:sqlite:2.2.0' implementation('org.apache.james:apache-mime4j:0.7.2') { exclude module: 'commons-io' } @@ -100,8 +99,8 @@ dependencies { implementation 'com.google.firebase:firebase-crashlytics:17.2.1' implementation 'androidx.legacy:legacy-support-core-ui:1.0.0' implementation 'com.duolingo.open:rtl-viewpager:2.0.0' - implementation("com.github.bumptech.glide:glide:4.9.0") { - exclude group: "com.android.support" + implementation('com.github.bumptech.glide:glide:4.9.0') { + exclude group: 'com.android.support' } implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" @@ -115,8 +114,8 @@ dependencies { implementation('io.ona.kujaku:library:0.9.0') { exclude module: 'xpp3' } - implementation "androidx.work:work-runtime:2.7.1" - implementation "androidx.work:work-runtime-ktx:2.7.1" + implementation 'androidx.work:work-runtime:2.7.1' + implementation 'androidx.work:work-runtime-ktx:2.7.1' implementation 'com.google.android.play:core:1.10.3' implementation 'android.arch.lifecycle:common-java8:1.1.1' @@ -139,28 +138,28 @@ ext { // Obtained from ~/.gradle/gradle.properties on build server (mobile agent), or your local // Obtained from ~/.gradle/gradle.properties on build server (mobile agent), or your local // ~/.gradle/gradle.properties file, or loads default empty strings if neither is present - MAPBOX_SDK_API_KEY = project.properties['MAPBOX_SDK_API_KEY'] ?: "" - ANALYTICS_TRACKING_ID_DEV = project.properties['ANALYTICS_TRACKING_ID_DEV'] ?: "" - ANALYTICS_TRACKING_ID_LIVE = project.properties['ANALYTICS_TRACKING_ID_LIVE'] ?: "" - GOOGLE_PLAY_MAPS_API_KEY = project.properties['GOOGLE_PLAY_MAPS_API_KEY'] ?: "" - RELEASE_STORE_FILE = project.properties['RELEASE_STORE_FILE'] ?: "." - RELEASE_STORE_PASSWORD = project.properties['RELEASE_STORE_PASSWORD'] ?: "" - RELEASE_KEY_ALIAS = project.properties['RELEASE_KEY_ALIAS'] ?: "" - RELEASE_KEY_PASSWORD = project.properties['RELEASE_KEY_PASSWORD'] ?: "" + MAPBOX_SDK_API_KEY = project.properties['MAPBOX_SDK_API_KEY'] ?: '' + ANALYTICS_TRACKING_ID_DEV = project.properties['ANALYTICS_TRACKING_ID_DEV'] ?: '' + ANALYTICS_TRACKING_ID_LIVE = project.properties['ANALYTICS_TRACKING_ID_LIVE'] ?: '' + GOOGLE_PLAY_MAPS_API_KEY = project.properties['GOOGLE_PLAY_MAPS_API_KEY'] ?: '' + RELEASE_STORE_FILE = project.properties['RELEASE_STORE_FILE'] ?: '.' + RELEASE_STORE_PASSWORD = project.properties['RELEASE_STORE_PASSWORD'] ?: '' + RELEASE_KEY_ALIAS = project.properties['RELEASE_KEY_ALIAS'] ?: '' + RELEASE_KEY_PASSWORD = project.properties['RELEASE_KEY_PASSWORD'] ?: '' TRUSTED_SOURCE_PUBLIC_KEY = project.properties['TRUSTED_SOURCE_PUBLIC_KEY'] ?: - "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDHiuy2ULV4pobkuQN2TEjmR1tn" + - "HJ+F335hm/lVdaFQzvBmeq64MUMbumheVLDJaSUiAVzqSHDKJWH01ZQRowqBYjwo" + - "ycVSQSeO2glc6XZZ+CJudAPXe8iFWLQp3kBBnBmVcBXCOQFO7aLgQMv4nqKZsLW0" + - "HaAJkjpnc165Os+aYwIDAQAB" - GOOGLE_SERVICES_API_KEY = project.properties['GOOGLE_SERVICES_API_KEY'] ?: "" - QA_BETA_APP_ID = "" - STANDALONE_APP_ID = "" - LTS_APP_ID = "" - COMMCARE_APP_ID = "" - HQ_API_USERNAME = project.properties['HQ_API_USERNAME'] ?: "" - HQ_API_PASSWORD = project.properties['HQ_API_PASSWORD'] ?: "" - TEST_BUILD_TYPE = project.properties['TEST_BUILD_TYPE'] ?: "debug" - FIREBASE_DATABASE_URL = project.properties['FIREBASE_DATABASE_URL'] ?: "" + 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDHiuy2ULV4pobkuQN2TEjmR1tn' + + 'HJ+F335hm/lVdaFQzvBmeq64MUMbumheVLDJaSUiAVzqSHDKJWH01ZQRowqBYjwo' + + 'ycVSQSeO2glc6XZZ+CJudAPXe8iFWLQp3kBBnBmVcBXCOQFO7aLgQMv4nqKZsLW0' + + 'HaAJkjpnc165Os+aYwIDAQAB' + GOOGLE_SERVICES_API_KEY = project.properties['GOOGLE_SERVICES_API_KEY'] ?: '' + QA_BETA_APP_ID = '' + STANDALONE_APP_ID = '' + LTS_APP_ID = '' + COMMCARE_APP_ID = '' + HQ_API_USERNAME = project.properties['HQ_API_USERNAME'] ?: '' + HQ_API_PASSWORD = project.properties['HQ_API_PASSWORD'] ?: '' + TEST_BUILD_TYPE = project.properties['TEST_BUILD_TYPE'] ?: 'debug' + FIREBASE_DATABASE_URL = project.properties['FIREBASE_DATABASE_URL'] ?: '' } afterEvaluate { @@ -189,11 +188,11 @@ task injectPropertiesIntoFirebaseConfigFile { } } -def ccAppId = project.hasProperty('cc_app_id') ? cc_app_id : "" -def ccDomain = project.hasProperty('cc_domain') ? cc_domain : "" -def isConsumerApp = project.hasProperty('is_consumer_app') ? is_consumer_app : "false" -def runDownloadScripts = project.hasProperty('run_download_scripts') ? run_download_scripts : "true" -def ccDomainSafe = ccDomain.replaceAll("-", "") +def ccAppId = project.hasProperty('cc_app_id') ? cc_app_id : '' +def ccDomain = project.hasProperty('cc_domain') ? cc_domain : '' +def isConsumerApp = project.hasProperty('is_consumer_app') ? is_consumer_app : 'false' +def runDownloadScripts = project.hasProperty('run_download_scripts') ? run_download_scripts : 'true' +def ccDomainSafe = ccDomain.replaceAll('-', '') def consumerAppUsername = getConsumerAppUsername(isConsumerApp) def consumerAppPassword = getConsumerAppPassword(isConsumerApp) @@ -215,12 +214,13 @@ static def getDate() { } android { - compileSdkVersion 33 + namespace 'org.commcare.dalvik' + compileSdk 33 lintOptions { abortOnError false disable 'MissingTranslation' - disable "ResourceType" + disable 'ResourceType' } // Espresso requires us to disable animations on device. @@ -236,18 +236,22 @@ android { exclude 'META-INF/NOTICE.txt' } + buildFeatures { + buildConfig true + } + defaultConfig { minSdkVersion 21 targetSdkVersion 33 multiDexEnabled true - applicationId "org.commcare.dalvik" - testNamespace "org.commcare.dalvik.test" + applicationId 'org.commcare.dalvik' + testNamespace 'org.commcare.dalvik.test' project.ext.COMMCARE_APP_ID = applicationId // set the app name - def applicationName = "CommCare" - resValue "string", "application_name", applicationName - def odkProviderStr = "org.commcare.android.provider.odk" + def applicationName = 'CommCare' + resValue 'string', 'application_name', applicationName + def odkProviderStr = 'org.commcare.android.provider.odk' manifestPlaceholders = [ odkProvider : odkProviderStr, googlePlayMapsApiKey: "${project.ext.GOOGLE_PLAY_MAPS_API_KEY}" @@ -257,28 +261,28 @@ android { // when set, app won't show install screen and try to install // resources from assets folder - buildConfigField "boolean", "IS_SINGLE_APP_BUILD", "false" - buildConfigField "boolean", "IS_CONSUMER_APP", "false" - buildConfigField "String", "CONSUMER_APP_USERNAME", "\"\"" - buildConfigField "String", "CONSUMER_APP_PASSWORD", "\"\"" + buildConfigField 'boolean', 'IS_SINGLE_APP_BUILD', 'false' + buildConfigField 'boolean', 'IS_CONSUMER_APP', 'false' + buildConfigField 'String', 'CONSUMER_APP_USERNAME', "\"\"" + buildConfigField 'String', 'CONSUMER_APP_PASSWORD', "\"\"" - buildConfigField "String", "CC_AUTHORITY", "\"${applicationId}\"" - buildConfigField "String", "ODK_AUTHORITY", "\"${odkProviderStr}\"" + buildConfigField 'String', 'CC_AUTHORITY', "\"${applicationId}\"" + buildConfigField 'String', 'ODK_AUTHORITY', "\"${odkProviderStr}\"" - buildConfigField "String", "BUILD_DATE", "\"" + getDate() + "\"" - buildConfigField "String", "BUILD_NUMBER", "\"" + computeVersionCode() + "\"" - buildConfigField "String", "TRUSTED_SOURCE_PUBLIC_KEY", "\"${project.ext.TRUSTED_SOURCE_PUBLIC_KEY}\"" - buildConfigField "String", "ANALYTICS_TRACKING_ID_LIVE", "\"${project.ext.ANALYTICS_TRACKING_ID_LIVE}\"" - buildConfigField "String", "ANALYTICS_TRACKING_ID_DEV", "\"${project.ext.ANALYTICS_TRACKING_ID_DEV}\"" - buildConfigField "String", "MAPBOX_SDK_API_KEY", "\"${project.ext.MAPBOX_SDK_API_KEY}\"" + buildConfigField 'String', 'BUILD_DATE', "\"" + getDate() + "\"" + buildConfigField 'String', 'BUILD_NUMBER', "\"" + computeVersionCode() + "\"" + buildConfigField 'String', 'TRUSTED_SOURCE_PUBLIC_KEY', "\"${project.ext.TRUSTED_SOURCE_PUBLIC_KEY}\"" + buildConfigField 'String', 'ANALYTICS_TRACKING_ID_LIVE', "\"${project.ext.ANALYTICS_TRACKING_ID_LIVE}\"" + buildConfigField 'String', 'ANALYTICS_TRACKING_ID_DEV', "\"${project.ext.ANALYTICS_TRACKING_ID_DEV}\"" + buildConfigField 'String', 'MAPBOX_SDK_API_KEY', "\"${project.ext.MAPBOX_SDK_API_KEY}\"" buildConfigField "String", "HQ_API_USERNAME", "\"${project.ext.HQ_API_USERNAME}\"" buildConfigField "String", "HQ_API_PASSWORD", "\"${project.ext.HQ_API_PASSWORD}\"" buildConfigField "String", "FIREBASE_DATABASE_URL", "\"${project.ext.FIREBASE_DATABASE_URL}\"" - buildConfigField "String", "CCC_HOST", "\"connect.dimagi.com\"" + buildConfigField 'String', 'CCC_HOST', "\"connect.dimagi.com\"" - testInstrumentationRunner "org.commcare.CommCareJUnitRunner" + testInstrumentationRunner 'org.commcare.CommCareJUnitRunner' } buildFeatures { @@ -286,7 +290,7 @@ android { } applicationVariants.all { variant -> - if (variant.buildType.name == "release") { + if (variant.buildType.name == 'release') { variant.outputs.each { output -> output.versionCodeOverride = computeVersionCode() } @@ -367,7 +371,7 @@ android { } // Our flavours doesn't differ on a particular dimension yet, so just specify a dummy - flavorDimensions "dummy" + flavorDimensions 'dummy' productFlavors { commcare { // builds normal commcare @@ -376,27 +380,27 @@ android { lts { // long term support build of CommCare - applicationId "org.commcare.lts" + applicationId 'org.commcare.lts' project.ext.LTS_APP_ID = applicationId // setup content provider strings correctly to not conflict with other apps - def odkProviderStr = "org.commcare.lts.provider.odk" + def odkProviderStr = 'org.commcare.lts.provider.odk' manifestPlaceholders = [odkProvider: odkProviderStr] - buildConfigField "String", "CC_AUTHORITY", "\"${applicationId}\"" - buildConfigField "String", "ODK_AUTHORITY", "\"${odkProviderStr}\"" + buildConfigField 'String', 'CC_AUTHORITY', "\"${applicationId}\"" + buildConfigField 'String', 'ODK_AUTHORITY', "\"${odkProviderStr}\"" // set the app name - def applicationName = "CommCare LTS" - resValue "string", "application_name", applicationName + def applicationName = 'CommCare LTS' + resValue 'string', 'application_name', applicationName } cccStaging { - buildConfigField "String", "CCC_HOST", "\"connect-staging.dimagi.com\"" + buildConfigField 'String', 'CCC_HOST', "\"connect-staging.dimagi.com\"" // set the app name - def applicationName = "CommCare (CCC Staging)" - resValue "string", "application_name", applicationName + def applicationName = 'CommCare (CCC Staging)' + resValue 'string', 'application_name', applicationName } standalone { @@ -408,41 +412,41 @@ android { applicationId "org.commcare.${uniquePackageIdentifier}" project.ext.STANDALONE_APP_ID = applicationId - resValue "string", "application_name", appDisplayName + resValue 'string', 'application_name', appDisplayName def odkProviderStr = "org.commcare.${uniquePackageIdentifier}.provider.odk" manifestPlaceholders = [odkProvider: odkProviderStr] - buildConfigField "boolean", "IS_SINGLE_APP_BUILD", "true" - buildConfigField "boolean", "IS_CONSUMER_APP", isConsumerApp - buildConfigField "String", "CONSUMER_APP_USERNAME", "\"${consumerAppUsername}\"" - buildConfigField "String", "CONSUMER_APP_PASSWORD", "\"${consumerAppPassword}\"" + buildConfigField 'boolean', 'IS_SINGLE_APP_BUILD', 'true' + buildConfigField 'boolean', 'IS_CONSUMER_APP', isConsumerApp + buildConfigField 'String', 'CONSUMER_APP_USERNAME', "\"${consumerAppUsername}\"" + buildConfigField 'String', 'CONSUMER_APP_PASSWORD', "\"${consumerAppPassword}\"" // include this again so that the value get reloaded - buildConfigField "String", "CC_AUTHORITY", "\"${applicationId}\"" - buildConfigField "String", "ODK_AUTHORITY", "\"${odkProviderStr}\"" + buildConfigField 'String', 'CC_AUTHORITY', "\"${applicationId}\"" + buildConfigField 'String', 'ODK_AUTHORITY', "\"${odkProviderStr}\"" } } buildTypes { debug { - applicationIdSuffix ".debug" - def applicationId = "org.commcare.dalvik.debug" + applicationIdSuffix '.debug' + def applicationId = 'org.commcare.dalvik.debug' project.ext.COMMCARE_APP_ID = applicationId - def applicationName = "CommCare Debug" - resValue "string", "application_name", applicationName - def odkProviderStr = "org.commcare.dalvik.debug.provider.odk" + def applicationName = 'CommCare Debug' + resValue 'string', 'application_name', applicationName + def odkProviderStr = 'org.commcare.dalvik.debug.provider.odk' manifestPlaceholders = [odkProvider: odkProviderStr] minifyEnabled false debuggable true // used in test suite to build the prototype factory; otherwise unneeded - buildConfigField "String", "CC_AUTHORITY", "\"${applicationId}\"" - buildConfigField "String", "ODK_AUTHORITY", "\"${odkProviderStr}\"" - buildConfigField "String", "BUILD_DIR", fixEscaping("\"${buildDir}\"") - buildConfigField "String", "PROJECT_DIR", fixEscaping("\"${projectDir}\"") + buildConfigField 'String', 'CC_AUTHORITY', "\"${applicationId}\"" + buildConfigField 'String', 'ODK_AUTHORITY', "\"${odkProviderStr}\"" + buildConfigField 'String', 'BUILD_DIR', fixEscaping("\"${buildDir}\"") + buildConfigField 'String', 'PROJECT_DIR', fixEscaping("\"${projectDir}\"") // disable crashlytics - buildConfigField "boolean", "USE_CRASHLYTICS", "false" + buildConfigField 'boolean', 'USE_CRASHLYTICS', 'false' ext.enableCrashlytics = false } @@ -450,10 +454,11 @@ android { minifyEnabled true signingConfig signingConfigs.release proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard.cfg' + testProguardFiles 'test-proguard.cfg' multiDexKeepProguard file('proguard-multidex.pro') // enable crashlytics - buildConfigField "boolean", "USE_CRASHLYTICS", "true" + buildConfigField 'boolean', 'USE_CRASHLYTICS', 'true' ext.enableCrashlytics = true } } @@ -495,7 +500,7 @@ downloadCCApp { doLast { if (execResult.exitValue != 0) { - throw new GradleException("exec failed; see output above") + throw new GradleException('exec failed; see output above') } } } @@ -503,11 +508,11 @@ downloadCCApp { // dynamic check at task execution time downloadCCApp { doLast { - if (ccAppId == "") { - throw new InvalidUserDataException("Please provide cc_app_id property (CommCare App ID) to be packaged with apk") + if (ccAppId == '') { + throw new InvalidUserDataException('Please provide cc_app_id property (CommCare App ID) to be packaged with apk') } - if (ccDomain == "") { - throw new InvalidUserDataException("Please provide cc_domain property (CommCare App Domain) to be packaged with apk") + if (ccDomain == '') { + throw new InvalidUserDataException('Please provide cc_domain property (CommCare App Domain) to be packaged with apk') } } } @@ -525,7 +530,7 @@ downloadRestoreFile { doLast { if (execResult.exitValue != 0) { - throw new GradleException("exec failed; see output above") + throw new GradleException('exec failed; see output above') } } } @@ -533,11 +538,11 @@ downloadRestoreFile { // dynamic check at task execution time downloadRestoreFile { doLast { - if (consumerAppUsername == "") { - throw new InvalidUserDataException("Please provide username for restore to be packaged with apk") + if (consumerAppUsername == '') { + throw new InvalidUserDataException('Please provide username for restore to be packaged with apk') } - if (consumerAppPassword == "") { - throw new InvalidUserDataException("Please provide password for restore to be packaged with apk") + if (consumerAppPassword == '') { + throw new InvalidUserDataException('Please provide password for restore to be packaged with apk') } } } @@ -545,7 +550,7 @@ downloadRestoreFile { // dynamically inject commcare app download into standalone build process tasks.whenTaskAdded { task -> if ((task.name == 'processStandaloneDebugResources' || - task.name == 'processStandaloneReleaseResources') && "true" == runDownloadScripts) { + task.name == 'processStandaloneReleaseResources') && 'true' == runDownloadScripts) { task.dependsOn downloadCCApp } if ((task.name == 'processStandaloneDebugResources' || @@ -564,45 +569,45 @@ static def numbersToLetters(String version) { StringBuilder words = new StringBuilder() for (String num : chars) { switch (num) { - case "1": words.append("one"); break - case "2": words.append("two"); break - case "3": words.append("three"); break - case "4": words.append("four"); break - case "5": words.append("five"); break - case "6": words.append("six"); break - case "7": words.append("seven"); break - case "8": words.append("eight"); break - case "9": words.append("nine"); break - case "0": words.append("zero"); break - default: break // skip non-numeric + case '1': words.append('one'); break + case '2': words.append('two'); break + case '3': words.append('three'); break + case '4': words.append('four'); break + case '5': words.append('five'); break + case '6': words.append('six'); break + case '7': words.append('seven'); break + case '8': words.append('eight'); break + case '9': words.append('nine'); break + case '0': words.append('zero'); break + default: break // skip non-numeric' } } return words.toString() } static def fixEscaping(String s) { - return s.replaceAll("\\\\", "\\\\\\\\") + return s.replaceAll('\\\\', '\\\\\\\\') } def getStandalonePackageIdentifier(ccDomainSafe, isConsumerApp) { if (project.hasProperty('application_name')) { - return ccDomainSafe + "." + cleanseAppNameForPackageIdentifier(application_name) - } else if ("true" == isConsumerApp) { - throw new InvalidUserDataException("An application_name property must be provided for consumer app standalone builds") + return ccDomainSafe + '.' + cleanseAppNameForPackageIdentifier(application_name) + } else if ('true' == isConsumerApp) { + throw new InvalidUserDataException('An application_name property must be provided for consumer app standalone builds') } else { return ccDomainSafe } } static def cleanseAppNameForPackageIdentifier(appName) { - return appName.replaceAll("[ '.:]", "").replaceAll("\\\\", "").toLowerCase() + return appName.replaceAll("[ '.:]", "").replaceAll('\\\\', '').toLowerCase() } def getStandaloneApplicationName(ccDomainSafe, isConsumerApp) { if (project.hasProperty('application_name')) { return application_name - } else if ("true" == isConsumerApp) { - throw new InvalidUserDataException("An application_name property must be provided for consumer app standalone builds") + } else if ('true' == isConsumerApp) { + throw new InvalidUserDataException('An application_name property must be provided for consumer app standalone builds') } else { return ccDomainSafe } @@ -611,20 +616,20 @@ def getStandaloneApplicationName(ccDomainSafe, isConsumerApp) { def getConsumerAppUsername(isConsumerApp) { if (project.hasProperty('username')) { return username - } else if ("true" == isConsumerApp) { - throw new InvalidUserDataException("A username property must be provided for consumer app standalone builds") + } else if ('true' == isConsumerApp) { + throw new InvalidUserDataException('A username property must be provided for consumer app standalone builds') } else { - return "" + return '' } } def getConsumerAppPassword(isConsumerApp) { if (project.hasProperty('password')) { return password - } else if ("true" == isConsumerApp) { - throw new InvalidUserDataException("A password property must be provided for consumer app standalone builds") + } else if ('true' == isConsumerApp) { + throw new InvalidUserDataException('A password property must be provided for consumer app standalone builds') } else { - return "" + return '' } } diff --git a/app/instrumentation-tests/AndroidManifest.xml b/app/instrumentation-tests/AndroidManifest.xml index fe2e5640d3..a05aaf4028 100644 --- a/app/instrumentation-tests/AndroidManifest.xml +++ b/app/instrumentation-tests/AndroidManifest.xml @@ -1,7 +1,6 @@ + xmlns:tools="http://schemas.android.com/tools"> diff --git a/app/instrumentation-tests/src/org/commcare/androidTests/AppPreferenceSettingsTest.kt b/app/instrumentation-tests/src/org/commcare/androidTests/AppPreferenceSettingsTest.kt index ce675dfcbe..df5f161afb 100644 --- a/app/instrumentation-tests/src/org/commcare/androidTests/AppPreferenceSettingsTest.kt +++ b/app/instrumentation-tests/src/org/commcare/androidTests/AppPreferenceSettingsTest.kt @@ -10,7 +10,12 @@ import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.contrib.RecyclerViewActions import androidx.test.espresso.intent.Intents.intended import androidx.test.espresso.intent.Intents.intending -import androidx.test.espresso.matcher.ViewMatchers.* +import androidx.test.espresso.matcher.ViewMatchers.hasDescendant +import androidx.test.espresso.matcher.ViewMatchers.isChecked +import androidx.test.espresso.matcher.ViewMatchers.isDisplayed +import androidx.test.espresso.matcher.ViewMatchers.withClassName +import androidx.test.espresso.matcher.ViewMatchers.withId +import androidx.test.espresso.matcher.ViewMatchers.withText import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.LargeTest import org.commcare.annotations.BrowserstackTests @@ -26,7 +31,7 @@ import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) @LargeTest @BrowserstackTests -class AppPreferenceSettingsTest: BaseTest() { +class AppPreferenceSettingsTest : BaseTest() { companion object { const val CCZ_NAME = "settings_sheet_tests.ccz" @@ -44,13 +49,13 @@ class AppPreferenceSettingsTest: BaseTest() { val settingName = "Fuzzy Search Matches" InstrumentationUtility.openOptionsMenu() onView(withText("Settings")) - .perform(click()) + .perform(click()) selectSetting(settingName) onView(withText("Enabled")) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) onView(withText("Disabled")) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) // Check enabled is selected by default matchSelectedPreference("Enabled") @@ -68,15 +73,15 @@ class AppPreferenceSettingsTest: BaseTest() { val settingName = "Auto Update Frequency" InstrumentationUtility.openOptionsMenu() onView(withText("Settings")) - .perform(click()) + .perform(click()) selectSetting(settingName) onView(withText("Never")) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) onView(withText("Daily")) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) onView(withText("Weekly")) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) // Change setting and check their persistence changePreferenceAndCheckPersistence("Daily", settingName) @@ -91,7 +96,7 @@ class AppPreferenceSettingsTest: BaseTest() { InstrumentationUtility.login("settings.test.3", "123") InstrumentationUtility.openOptionsMenu() onView(withText("Settings")) - .perform(click()) + .perform(click()) selectSetting("Set Print Template") //Create a dummy file selection intent @@ -102,7 +107,7 @@ class AppPreferenceSettingsTest: BaseTest() { // Click on file fetch onView(withId(R.id.filefetch)) - .perform(click()) + .perform(click()) // Confirm that the file selection intent was called. intended(expectedIntent) @@ -110,26 +115,26 @@ class AppPreferenceSettingsTest: BaseTest() { private fun selectSetting(text: String) { onView(withText("CommCare > Settings")) - .check(matches(isDisplayed())) - onView(withId(R.id.recycler_view)) - .perform(RecyclerViewActions.scrollTo( - hasDescendant(withText(text)) + .check(matches(isDisplayed())) + onView(withId(androidx.preference.R.id.recycler_view)) + .perform(RecyclerViewActions.scrollTo( + hasDescendant(withText(text)) )) onView(withText(text)) - .perform(click()) + .perform(click()) } private fun cancelSettingChangeDialog() { onView(withText("CANCEL")) - .perform(click()) + .perform(click()) onView(withText("CommCare > Settings")) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) } private fun changePreferenceAndCheckPersistence(newPref: String, setting: String) { // Change to new preference onView(withText(newPref)) - .perform(click()) + .perform(click()) //Rotate and check the selection persists. InstrumentationUtility.rotateLeft() @@ -142,8 +147,8 @@ class AppPreferenceSettingsTest: BaseTest() { private fun matchSelectedPreference(value: String) { onView(allOf( - withClassName(endsWith("AppCompatCheckedTextView")), - withText(value) + withClassName(endsWith("AppCompatCheckedTextView")), + withText(value) )).check(matches(isChecked())) } diff --git a/app/instrumentation-tests/src/org/commcare/utils/InstrumentationUtility.kt b/app/instrumentation-tests/src/org/commcare/utils/InstrumentationUtility.kt index 335637f788..7fc13ce7eb 100644 --- a/app/instrumentation-tests/src/org/commcare/utils/InstrumentationUtility.kt +++ b/app/instrumentation-tests/src/org/commcare/utils/InstrumentationUtility.kt @@ -15,17 +15,33 @@ import android.widget.TextView import androidx.annotation.IdRes import androidx.appcompat.app.AppCompatActivity import androidx.preference.PreferenceManager -import androidx.test.espresso.* -import androidx.test.espresso.Espresso.* -import androidx.test.espresso.action.ViewActions.* +import androidx.test.espresso.DataInteraction +import androidx.test.espresso.Espresso +import androidx.test.espresso.Espresso.onData +import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu +import androidx.test.espresso.PerformException +import androidx.test.espresso.UiController +import androidx.test.espresso.ViewAction +import androidx.test.espresso.ViewInteraction +import androidx.test.espresso.action.ViewActions.clearText +import androidx.test.espresso.action.ViewActions.click +import androidx.test.espresso.action.ViewActions.swipeUp +import androidx.test.espresso.action.ViewActions.typeText import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.intent.Intents import androidx.test.espresso.intent.Intents.intending import androidx.test.espresso.intent.matcher.IntentMatchers import androidx.test.espresso.intent.matcher.IntentMatchers.hasAction import androidx.test.espresso.matcher.RootMatchers -import androidx.test.espresso.matcher.ViewMatchers -import androidx.test.espresso.matcher.ViewMatchers.* +import androidx.test.espresso.matcher.ViewMatchers.hasSibling +import androidx.test.espresso.matcher.ViewMatchers.isAssignableFrom +import androidx.test.espresso.matcher.ViewMatchers.isDisplayed +import androidx.test.espresso.matcher.ViewMatchers.isRoot +import androidx.test.espresso.matcher.ViewMatchers.withChild +import androidx.test.espresso.matcher.ViewMatchers.withClassName +import androidx.test.espresso.matcher.ViewMatchers.withId +import androidx.test.espresso.matcher.ViewMatchers.withText import androidx.test.espresso.util.HumanReadables import androidx.test.espresso.util.TreeIterables import androidx.test.platform.app.InstrumentationRegistry @@ -38,15 +54,15 @@ import org.commcare.CommCareInstrumentationTestApplication import org.commcare.dalvik.R import org.commcare.services.CommCareSessionService import org.commcare.utils.CustomMatchers.withChildViewCount +import org.hamcrest.CoreMatchers.anything +import org.hamcrest.CoreMatchers.startsWith import org.hamcrest.Matcher import org.hamcrest.Matchers -import org.hamcrest.Matchers.* import org.hamcrest.StringDescription import org.javarosa.core.io.StreamsUtil import org.junit.Assert.assertTrue import java.io.File import java.io.IOException -import java.util.* import java.util.concurrent.TimeUnit import java.util.concurrent.TimeoutException @@ -81,26 +97,26 @@ object InstrumentationUtility { stubCcz(cczName) openOptionsMenu() onView(withText("Offline Install")) - .perform(click()) + .perform(click()) onView(withId(R.id.screen_multimedia_inflater_filefetch)) - .perform(click()) + .perform(click()) onView(withId(R.id.screen_multimedia_inflater_install)) - .perform(click()) + .perform(click()) } @JvmStatic fun uninstallCurrentApp() { openOptionsMenu() onView(withText("Go To App Manager")) - .perform(click()) + .perform(click()) clickListItem(R.id.apps_list_view, 0) onView(withText("Uninstall")) - .perform(click()) + .perform(click()) onView(withText("OK")) - .inRoot(RootMatchers.isDialog()) - .perform(click()) + .inRoot(RootMatchers.isDialog()) + .perform(click()) onView(withId(R.id.install_app_button)) - .perform(click()) + .perform(click()) } @JvmStatic @@ -109,21 +125,21 @@ object InstrumentationUtility { enterText(R.id.edit_password, password) onView(isRoot()).perform(swipeUp()) onView(withId(R.id.login_button)) - .perform(click()) + .perform(click()) } @JvmStatic fun openModule(text: String) { onView(withText("Start")) - .perform(click()) + .perform(click()) onView(withText(text)) - .perform(click()) + .perform(click()) } @JvmStatic fun openModule(module: Int) { onView(withText("Start")) - .perform(click()) + .perform(click()) clickListItem(R.id.screen_suite_menu_list, module) } @@ -145,9 +161,9 @@ object InstrumentationUtility { for (i in 0..3) { openOptionsMenu() onView(withText("About CommCare")) - .perform(click()) + .perform(click()) onView(withText("OK")) - .perform(click()) + .perform(click()) } } @@ -159,9 +175,9 @@ object InstrumentationUtility { @JvmStatic fun clickListItem(@IdRes resId: Int, position: Int) { onData(anything()) - .inAdapterView(withId(resId)) - .atPosition(position) - .perform(click()) + .inAdapterView(withId(resId)) + .atPosition(position) + .perform(click()) } /** @@ -173,9 +189,9 @@ object InstrumentationUtility { @JvmStatic fun getSubViewInListItem(@IdRes listId: Int, position: Int, @IdRes subviewId: Int): DataInteraction { return onData(anything()) - .inAdapterView(withId(listId)) - .atPosition(position) - .onChildView(withId(subviewId)) + .inAdapterView(withId(listId)) + .atPosition(position) + .onChildView(withId(subviewId)) } /** @@ -185,7 +201,7 @@ object InstrumentationUtility { @JvmStatic fun openFirstIncompleteForm() { onView(withText(startsWith("Incomplete"))) - .perform(click()) + .perform(click()) clickListItem(R.id.screen_entity_select_list, 0) } @@ -193,9 +209,9 @@ object InstrumentationUtility { fun logout() { gotoHome() onView(withId(R.id.home_gridview_buttons)) - .perform(swipeUp()) + .perform(swipeUp()) onView(withText("Log out of CommCare")) - .perform(click()) + .perform(click()) } /** @@ -207,7 +223,7 @@ object InstrumentationUtility { var intentCallback = onImageCaptureIntentSent() IntentMonitorRegistry.getInstance().addIntentCallback(intentCallback) onView(withText(R.string.capture_image)) - .perform(click()) + .perform(click()) IntentMonitorRegistry.getInstance().removeIntentCallback(intentCallback) } @@ -217,7 +233,7 @@ object InstrumentationUtility { @JvmStatic fun nextPage() { onView(withId(R.id.nav_btn_next)) - .perform(click()) + .perform(click()) } /** @@ -235,9 +251,9 @@ object InstrumentationUtility { @JvmStatic fun sleep(seconds: Int) { onView(isRoot()) - .perform(sleep( - TimeUnit.SECONDS.toMillis(seconds.toLong()) - )) + .perform(sleep( + TimeUnit.SECONDS.toMillis(seconds.toLong()) + )) } /** @@ -246,10 +262,10 @@ object InstrumentationUtility { @JvmStatic fun matchChildCount(parent: Class<*>, child: Class<*>, count: Int) { onView(withClassName(Matchers.`is`(parent.canonicalName))) - .check(matches( - withChildViewCount(count, - withClassName(Matchers.`is`(child.canonicalName))) - )) + .check(matches( + withChildViewCount(count, + withClassName(Matchers.`is`(child.canonicalName))) + )) } /** @@ -259,9 +275,9 @@ object InstrumentationUtility { @JvmStatic fun getListSize(@IdRes resId: Int): Int { val application = InstrumentationRegistry - .getInstrumentation() - .targetContext - .applicationContext as CommCareInstrumentationTestApplication + .getInstrumentation() + .targetContext + .applicationContext as CommCareInstrumentationTestApplication val activity = application.currentActivity val listView = activity.findViewById(resId) return listView.adapter.count @@ -290,21 +306,22 @@ object InstrumentationUtility { @JvmStatic fun enterText(@IdRes editTextId: Int, text: String) { onView(withId(editTextId)) - .perform(clearText()) + .perform(clearText()) onView(withId(editTextId)) - .perform(typeText(text)) + .perform(typeText(text)) Espresso.closeSoftKeyboard() } fun enterText(text: String) { onView(withClassName(Matchers.endsWith("EditText"))) - .perform(typeText((text))) + .perform(typeText((text))) Espresso.closeSoftKeyboard() } + /** * A utility to match the text present in a textfield */ - fun matchTypedText(@IdRes editTextId: Int, text: String){ + fun matchTypedText(@IdRes editTextId: Int, text: String) { onView(withId(editTextId)).check(matches(withText(text))) } @@ -353,6 +370,7 @@ object InstrumentationUtility { val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) mDevice.pressBack() } + /** * The method does following in order: * 1. Closes keyboard. @@ -364,7 +382,7 @@ object InstrumentationUtility { Espresso.closeSoftKeyboard() Espresso.pressBack() onView(withText(backOption)) - .perform(click()) + .perform(click()) } /** @@ -376,11 +394,11 @@ object InstrumentationUtility { fun selectOptionItem(matcher: Matcher) { openOptionsMenu() onView(matcher) - .perform(click()) + .perform(click()) } @JvmStatic - fun stubIntentWithAction(action : String) { + fun stubIntentWithAction(action: String) { Intents.intending(IntentMatchers.hasAction(action)) .respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, Intent())) } @@ -394,7 +412,7 @@ object InstrumentationUtility { @JvmStatic fun assertCurrentActivity(clazz: Class) { val application = InstrumentationRegistry.getInstrumentation().targetContext.applicationContext - as CommCareInstrumentationTestApplication + as CommCareInstrumentationTestApplication val activity = application.currentActivity assert(clazz.isInstance(activity), "Current Activity is ${activity.localClassName}") } @@ -461,14 +479,12 @@ object InstrumentationUtility { } } - - /** * A utility to verify Form Fields with their values */ fun verifyFormCellAndValue(cellData: String, value: String) { - val result : Boolean = onView( + val result: Boolean = onView( Matchers.allOf( withId(R.id.detail_type_text), withText(cellData), @@ -491,9 +507,9 @@ object InstrumentationUtility { /** * utility to search a case in Form list and select the same */ - fun searchCaseAndSelect(text: String){ + fun searchCaseAndSelect(text: String) { onView(withId(R.id.search_action_bar)).perform(click()) - enterText(R.id.search_src_text,text) + enterText(androidx.appcompat.R.id.search_src_text, text) onView(withId(R.id.screen_entity_detail_list)).isPresent() clickListItem(R.id.screen_entity_select_list, 0) } diff --git a/app/jacoco.gradle b/app/jacoco.gradle index 89889f928b..36776971ea 100644 --- a/app/jacoco.gradle +++ b/app/jacoco.gradle @@ -13,8 +13,8 @@ android { task jacocoTestReport(type: JacocoReport, dependsOn: ['testCommcareDebugUnitTest']) { reports { - xml.enabled = true - html.enabled = true + xml.required = true + html.required = true } def fileFilter = ['**/R.class', '**/R$*.class', diff --git a/app/proguard.cfg b/app/proguard.cfg index a1b1a8a5ec..5cf741f60b 100644 --- a/app/proguard.cfg +++ b/app/proguard.cfg @@ -53,6 +53,8 @@ -dontwarn sun.misc.Unsafe -dontwarn org.xmlpull.v1.** +-dontwarn org.kxml2.io.** +-dontwarn android.content.res.** -dontwarn javax.annotation.**,javax.microedition.** -dontwarn org.apache.** -dontwarn org.joda.** @@ -102,6 +104,7 @@ -dontnote okhttp3.** #Retrofit Stuff +-keep class retrofit2.Call { *; } -dontnote retrofit2.Platform -dontwarn retrofit2.Platform$Java8 -keepattributes Signature diff --git a/app/test-proguard.cfg b/app/test-proguard.cfg new file mode 100644 index 0000000000..79e8605b0a --- /dev/null +++ b/app/test-proguard.cfg @@ -0,0 +1,260 @@ +-dontwarn com.sun.javadoc.ClassDoc +-dontwarn com.sun.javadoc.Doc +-dontwarn com.sun.javadoc.DocErrorReporter +-dontwarn com.sun.javadoc.FieldDoc +-dontwarn com.sun.javadoc.RootDoc +-dontwarn com.sun.javadoc.SeeTag +-dontwarn com.sun.javadoc.Tag +-dontwarn com.sun.source.tree.AnnotatedTypeTree +-dontwarn com.sun.source.tree.AnnotationTree +-dontwarn com.sun.source.tree.ArrayAccessTree +-dontwarn com.sun.source.tree.ArrayTypeTree +-dontwarn com.sun.source.tree.AssertTree +-dontwarn com.sun.source.tree.AssignmentTree +-dontwarn com.sun.source.tree.BinaryTree +-dontwarn com.sun.source.tree.BlockTree +-dontwarn com.sun.source.tree.BreakTree +-dontwarn com.sun.source.tree.CaseTree +-dontwarn com.sun.source.tree.CatchTree +-dontwarn com.sun.source.tree.ClassTree +-dontwarn com.sun.source.tree.CompilationUnitTree +-dontwarn com.sun.source.tree.CompoundAssignmentTree +-dontwarn com.sun.source.tree.ConditionalExpressionTree +-dontwarn com.sun.source.tree.ContinueTree +-dontwarn com.sun.source.tree.DoWhileLoopTree +-dontwarn com.sun.source.tree.EmptyStatementTree +-dontwarn com.sun.source.tree.EnhancedForLoopTree +-dontwarn com.sun.source.tree.ErroneousTree +-dontwarn com.sun.source.tree.ExpressionStatementTree +-dontwarn com.sun.source.tree.ExpressionTree +-dontwarn com.sun.source.tree.ForLoopTree +-dontwarn com.sun.source.tree.IdentifierTree +-dontwarn com.sun.source.tree.IfTree +-dontwarn com.sun.source.tree.ImportTree +-dontwarn com.sun.source.tree.InstanceOfTree +-dontwarn com.sun.source.tree.IntersectionTypeTree +-dontwarn com.sun.source.tree.LabeledStatementTree +-dontwarn com.sun.source.tree.LambdaExpressionTree$BodyKind +-dontwarn com.sun.source.tree.LambdaExpressionTree +-dontwarn com.sun.source.tree.LineMap +-dontwarn com.sun.source.tree.LiteralTree +-dontwarn com.sun.source.tree.MemberReferenceTree$ReferenceMode +-dontwarn com.sun.source.tree.MemberReferenceTree +-dontwarn com.sun.source.tree.MemberSelectTree +-dontwarn com.sun.source.tree.MethodInvocationTree +-dontwarn com.sun.source.tree.MethodTree +-dontwarn com.sun.source.tree.ModifiersTree +-dontwarn com.sun.source.tree.NewArrayTree +-dontwarn com.sun.source.tree.NewClassTree +-dontwarn com.sun.source.tree.ParameterizedTypeTree +-dontwarn com.sun.source.tree.ParenthesizedTree +-dontwarn com.sun.source.tree.PrimitiveTypeTree +-dontwarn com.sun.source.tree.ReturnTree +-dontwarn com.sun.source.tree.Scope +-dontwarn com.sun.source.tree.StatementTree +-dontwarn com.sun.source.tree.SwitchTree +-dontwarn com.sun.source.tree.SynchronizedTree +-dontwarn com.sun.source.tree.ThrowTree +-dontwarn com.sun.source.tree.Tree$Kind +-dontwarn com.sun.source.tree.Tree +-dontwarn com.sun.source.tree.TreeVisitor +-dontwarn com.sun.source.tree.TryTree +-dontwarn com.sun.source.tree.TypeCastTree +-dontwarn com.sun.source.tree.TypeParameterTree +-dontwarn com.sun.source.tree.UnaryTree +-dontwarn com.sun.source.tree.UnionTypeTree +-dontwarn com.sun.source.tree.VariableTree +-dontwarn com.sun.source.tree.WhileLoopTree +-dontwarn com.sun.source.tree.WildcardTree +-dontwarn com.sun.source.util.JavacTask +-dontwarn com.sun.source.util.SimpleTreeVisitor +-dontwarn com.sun.source.util.SourcePositions +-dontwarn com.sun.source.util.TaskEvent$Kind +-dontwarn com.sun.source.util.TaskEvent +-dontwarn com.sun.source.util.TaskListener +-dontwarn com.sun.source.util.TreePath +-dontwarn com.sun.source.util.TreePathScanner +-dontwarn com.sun.source.util.TreeScanner +-dontwarn com.sun.source.util.Trees +-dontwarn com.sun.tools.javac.Main +-dontwarn com.sun.tools.javac.api.JavacScope +-dontwarn com.sun.tools.javac.api.JavacTaskImpl +-dontwarn com.sun.tools.javac.code.Attribute$Array +-dontwarn com.sun.tools.javac.code.Attribute$Class +-dontwarn com.sun.tools.javac.code.Attribute$Compound +-dontwarn com.sun.tools.javac.code.Attribute$Constant +-dontwarn com.sun.tools.javac.code.Attribute$Enum +-dontwarn com.sun.tools.javac.code.Attribute$TypeCompound +-dontwarn com.sun.tools.javac.code.Attribute +-dontwarn com.sun.tools.javac.code.BoundKind +-dontwarn com.sun.tools.javac.code.Kinds$Kind +-dontwarn com.sun.tools.javac.code.Kinds$KindSelector +-dontwarn com.sun.tools.javac.code.Source +-dontwarn com.sun.tools.javac.code.Symbol$ClassSymbol +-dontwarn com.sun.tools.javac.code.Symbol$Completer +-dontwarn com.sun.tools.javac.code.Symbol$CompletionFailure +-dontwarn com.sun.tools.javac.code.Symbol$MethodSymbol +-dontwarn com.sun.tools.javac.code.Symbol$PackageSymbol +-dontwarn com.sun.tools.javac.code.Symbol$TypeSymbol +-dontwarn com.sun.tools.javac.code.Symbol$TypeVariableSymbol +-dontwarn com.sun.tools.javac.code.Symbol$VarSymbol +-dontwarn com.sun.tools.javac.code.Symbol +-dontwarn com.sun.tools.javac.code.Symtab +-dontwarn com.sun.tools.javac.code.TargetType +-dontwarn com.sun.tools.javac.code.Type$ArrayType +-dontwarn com.sun.tools.javac.code.Type$CapturedType +-dontwarn com.sun.tools.javac.code.Type$ClassType +-dontwarn com.sun.tools.javac.code.Type$JCNoType +-dontwarn com.sun.tools.javac.code.Type$MethodType +-dontwarn com.sun.tools.javac.code.Type$TypeVar +-dontwarn com.sun.tools.javac.code.Type$UnionClassType +-dontwarn com.sun.tools.javac.code.Type$Visitor +-dontwarn com.sun.tools.javac.code.Type$WildcardType +-dontwarn com.sun.tools.javac.code.Type +-dontwarn com.sun.tools.javac.code.TypeAnnotationPosition$TypePathEntry +-dontwarn com.sun.tools.javac.code.TypeAnnotationPosition$TypePathEntryKind +-dontwarn com.sun.tools.javac.code.TypeAnnotationPosition +-dontwarn com.sun.tools.javac.code.TypeTag +-dontwarn com.sun.tools.javac.code.Types$SimpleVisitor +-dontwarn com.sun.tools.javac.code.Types +-dontwarn com.sun.tools.javac.comp.CompileStates$CompileState +-dontwarn com.sun.tools.javac.comp.DeferredAttr$AttrMode +-dontwarn com.sun.tools.javac.comp.Env +-dontwarn com.sun.tools.javac.comp.Resolve$RecoveryLoadClass +-dontwarn com.sun.tools.javac.comp.Resolve +-dontwarn com.sun.tools.javac.file.JavacFileManager +-dontwarn com.sun.tools.javac.main.CommandLine +-dontwarn com.sun.tools.javac.main.JavaCompiler +-dontwarn com.sun.tools.javac.main.Option +-dontwarn com.sun.tools.javac.model.JavacElements +-dontwarn com.sun.tools.javac.model.JavacTypes +-dontwarn com.sun.tools.javac.processing.JavacProcessingEnvironment +-dontwarn com.sun.tools.javac.tree.EndPosTable +-dontwarn com.sun.tools.javac.tree.JCTree +-dontwarn com.sun.tools.javac.tree.JCTree$* +-dontwarn com.sun.tools.javac.tree.Pretty +-dontwarn com.sun.tools.javac.tree.TreeInfo +-dontwarn com.sun.tools.javac.tree.TreeMaker +-dontwarn com.sun.tools.javac.util.AbstractLog +-dontwarn com.sun.tools.javac.util.Context +-dontwarn com.sun.tools.javac.util.DiagnosticSource +-dontwarn com.sun.tools.javac.util.JCDiagnostic$DiagnosticPosition +-dontwarn com.sun.tools.javac.util.List +-dontwarn com.sun.tools.javac.util.ListBuffer +-dontwarn com.sun.tools.javac.util.Log$DiagnosticHandler +-dontwarn com.sun.tools.javac.util.Log$DiscardDiagnosticHandler +-dontwarn com.sun.tools.javac.util.Log +-dontwarn com.sun.tools.javac.util.Name +-dontwarn com.sun.tools.javac.util.Names +-dontwarn com.sun.tools.javac.util.Options +-dontwarn com.sun.tools.javac.util.Pair +-dontwarn java.awt.CardLayout +-dontwarn java.awt.Color +-dontwarn java.awt.Component +-dontwarn java.awt.Container +-dontwarn java.awt.Dialog +-dontwarn java.awt.Dimension +-dontwarn java.awt.Frame +-dontwarn java.awt.GridLayout +-dontwarn java.awt.LayoutManager +-dontwarn java.awt.SystemColor +-dontwarn java.awt.Toolkit +-dontwarn java.awt.event.ActionEvent +-dontwarn java.awt.event.ActionListener +-dontwarn java.awt.event.WindowAdapter +-dontwarn java.awt.event.WindowEvent +-dontwarn java.awt.event.WindowListener +-dontwarn java.awt.image.BufferedImage +-dontwarn java.lang.ClassValue +-dontwarn java.lang.management.ManagementFactory +-dontwarn java.lang.management.MemoryPoolMXBean +-dontwarn java.lang.management.MemoryType +-dontwarn java.lang.management.MemoryUsage +-dontwarn java.lang.reflect.AnnotatedType +-dontwarn javax.annotation.processing.AbstractProcessor +-dontwarn javax.annotation.processing.Messager +-dontwarn javax.annotation.processing.ProcessingEnvironment +-dontwarn javax.annotation.processing.RoundEnvironment +-dontwarn javax.annotation.processing.SupportedAnnotationTypes +-dontwarn javax.annotation.processing.SupportedOptions +-dontwarn javax.annotation.processing.SupportedSourceVersion +-dontwarn javax.lang.model.SourceVersion +-dontwarn javax.lang.model.element.AnnotationMirror +-dontwarn javax.lang.model.element.AnnotationValue +-dontwarn javax.lang.model.element.AnnotationValueVisitor +-dontwarn javax.lang.model.element.Element +-dontwarn javax.lang.model.element.ElementKind +-dontwarn javax.lang.model.element.ElementVisitor +-dontwarn javax.lang.model.element.ExecutableElement +-dontwarn javax.lang.model.element.Modifier +-dontwarn javax.lang.model.element.Name +-dontwarn javax.lang.model.element.NestingKind +-dontwarn javax.lang.model.element.PackageElement +-dontwarn javax.lang.model.element.TypeElement +-dontwarn javax.lang.model.element.TypeParameterElement +-dontwarn javax.lang.model.element.VariableElement +-dontwarn javax.lang.model.type.ArrayType +-dontwarn javax.lang.model.type.DeclaredType +-dontwarn javax.lang.model.type.ErrorType +-dontwarn javax.lang.model.type.ExecutableType +-dontwarn javax.lang.model.type.IntersectionType +-dontwarn javax.lang.model.type.MirroredTypesException +-dontwarn javax.lang.model.type.NoType +-dontwarn javax.lang.model.type.NullType +-dontwarn javax.lang.model.type.PrimitiveType +-dontwarn javax.lang.model.type.ReferenceType +-dontwarn javax.lang.model.type.TypeKind +-dontwarn javax.lang.model.type.TypeMirror +-dontwarn javax.lang.model.type.TypeVariable +-dontwarn javax.lang.model.type.TypeVisitor +-dontwarn javax.lang.model.type.UnionType +-dontwarn javax.lang.model.type.WildcardType +-dontwarn javax.lang.model.util.AbstractElementVisitor7 +-dontwarn javax.lang.model.util.ElementFilter +-dontwarn javax.lang.model.util.Elements +-dontwarn javax.lang.model.util.SimpleElementVisitor7 +-dontwarn javax.lang.model.util.SimpleTypeVisitor7 +-dontwarn javax.lang.model.util.Types +-dontwarn javax.management.MBeanServer +-dontwarn javax.management.MBeanServerConnection +-dontwarn javax.script.ScriptEngine +-dontwarn javax.script.ScriptEngineManager +-dontwarn javax.swing.BorderFactory +-dontwarn javax.swing.JButton +-dontwarn javax.swing.JDialog +-dontwarn javax.swing.JFrame +-dontwarn javax.swing.JList +-dontwarn javax.swing.JMenu +-dontwarn javax.swing.JMenuBar +-dontwarn javax.swing.JMenuItem +-dontwarn javax.swing.JOptionPane +-dontwarn javax.swing.JPanel +-dontwarn javax.swing.JScrollPane +-dontwarn javax.swing.JSplitPane +-dontwarn javax.swing.JTextPane +-dontwarn javax.swing.JViewport +-dontwarn javax.swing.KeyStroke +-dontwarn javax.swing.ListModel +-dontwarn javax.swing.UIManager +-dontwarn javax.swing.border.Border +-dontwarn javax.swing.event.ListDataEvent +-dontwarn javax.swing.event.ListDataListener +-dontwarn javax.swing.event.ListSelectionEvent +-dontwarn javax.swing.event.ListSelectionListener +-dontwarn javax.tools.Diagnostic$Kind +-dontwarn javax.tools.Diagnostic +-dontwarn javax.tools.DiagnosticCollector +-dontwarn javax.tools.DiagnosticListener +-dontwarn javax.tools.JavaCompiler$CompilationTask +-dontwarn javax.tools.JavaCompiler +-dontwarn javax.tools.JavaFileManager +-dontwarn javax.tools.JavaFileObject +-dontwarn javax.tools.StandardJavaFileManager +-dontwarn javax.tools.ToolProvider +-dontwarn org.objectweb.asm.ClassReader +-dontwarn org.objectweb.asm.ClassVisitor +-dontwarn org.objectweb.asm.Handle +-dontwarn org.objectweb.asm.Label +-dontwarn org.objectweb.asm.MethodVisitor +-dontwarn org.objectweb.asm.Opcodes +-dontwarn org.objectweb.asm.Type \ No newline at end of file diff --git a/build.gradle b/build.gradle index 452d538b1c..27b287952c 100644 --- a/build.gradle +++ b/build.gradle @@ -7,11 +7,11 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:7.4.1' + classpath 'com.android.tools.build:gradle:8.0.1' classpath 'com.google.gms:google-services:4.3.14' classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - classpath 'org.jacoco:org.jacoco.core:0.8.8' + classpath 'org.jacoco:org.jacoco.core:0.8.10' classpath 'com.vanniktech:gradle-maven-publish-plugin:0.15.1' } } diff --git a/commcare-support-library/build.gradle b/commcare-support-library/build.gradle index dfb24782f6..90e68ba167 100644 --- a/commcare-support-library/build.gradle +++ b/commcare-support-library/build.gradle @@ -39,6 +39,7 @@ afterEvaluate { } android { + namespace "org.commcare.commcaresupportlibrary" compileSdk 33 defaultConfig { minSdkVersion 21 @@ -51,6 +52,12 @@ android { proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } + publishing { + singleVariant("release") { + withSourcesJar() + withJavadocJar() + } + } } dependencies { diff --git a/gradle.properties b/gradle.properties index 8a9ce1ad11..5c4c18bd18 100644 --- a/gradle.properties +++ b/gradle.properties @@ -21,4 +21,7 @@ org.gradle.configureondemand=false android.useAndroidX=true # automatically migrates existing third-party libraries to use AndroidX by rewriting their binaries -android.enableJetifier=true \ No newline at end of file +android.enableJetifier=true + +# generate R classes with final fields +android.nonFinalResIds=false \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 51cec56f04..7dc64c5911 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Fri Feb 10 10:17:15 SAST 2023 distributionBase=GRADLE_USER_HOME -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip distributionPath=wrapper/dists zipStorePath=wrapper/dists zipStoreBase=GRADLE_USER_HOME