Skip to content

Commit

Permalink
Android AGP 8.0 support (#1017)
Browse files Browse the repository at this point in the history
* skip downloading desktop builds

* Upgrade to AGP 8.0

* revert CI changes

* update kotlin version, use gradle 8.6

* update proguard rules

* Update gradle.properties

* Add code cleanup changes

* build with -ldflags -w

* remove multidex support

* update Application class

* update Gradle build configuration

* test building APK

* update java version

---------

Co-authored-by: atavism <[email protected]>
  • Loading branch information
jigar-f and atavism authored Mar 14, 2024
1 parent e40bf41 commit 4ed680b
Show file tree
Hide file tree
Showing 18 changed files with 96 additions and 89 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Publish releases

on:
push:
branches: [ main ]
branches: [ atavism/android-agp-8.0 ]
tags:
- '*'

Expand Down Expand Up @@ -155,11 +155,11 @@ jobs:
organization: getlantern
project: android

- name: Setup JDK 11
uses: actions/setup-java@v3
- name: Setup JDK
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 11
java-version: 17

- name: Generate ffi bindings
run: |
Expand Down
9 changes: 4 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,8 @@ else ifeq ($(ANDROID_ARCH), all)
# Note - we exclude x86 because flutter does not support x86. By excluding x86
# native libs, 32 bit Intel devices will just emulate ARM.
# DO NOT ADD x86 TO THIS LIST!!
ANDROID_ARCH_JAVA := armeabi-v7a arm64-v8a x86_64
ANDROID_ARCH_GOMOBILE := android/arm,android/arm64,android/amd64
ANDROID_ARCH_JAVA := arm64-v8a x86_64
ANDROID_ARCH_GOMOBILE := android/arm64,android/amd64
APK_QUALIFIER :=
else
$(error unsupported ANDROID_ARCH "$(ANDROID_ARCH)")
Expand Down Expand Up @@ -354,13 +354,12 @@ $(ANDROID_LIB): $(GO_SOURCES)
-target=$(ANDROID_ARCH_GOMOBILE) \
-tags='headless lantern' -o=$(ANDROID_LIB) \
-androidapi=23 \
-ldflags="$(LDFLAGS)" \
-ldflags="-s -w $(LDFLAGS)" \
$(GOMOBILE_EXTRA_BUILD_FLAGS) \
github.com/getlantern/lantern-client/internalsdk github.com/getlantern/pathdb/testsupport github.com/getlantern/pathdb/minisql

$(MOBILE_ANDROID_LIB): $(ANDROID_LIB)
mkdir -p $(MOBILE_LIBS) && \
cp $(ANDROID_LIB) $(MOBILE_ANDROID_LIB)
mkdir -p $(MOBILE_LIBS) && cp $(ANDROID_LIB) $(MOBILE_ANDROID_LIB)

.PHONY: android-lib appium-test-build
android-lib: $(MOBILE_ANDROID_LIB)
Expand Down
52 changes: 17 additions & 35 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'dev.flutter.flutter-gradle-plugin'
id 'org.jlleitschuh.gradle.ktlint'
id 'org.jetbrains.kotlin.android'
id 'kotlin-parcelize'
Expand All @@ -9,33 +10,6 @@ plugins {
id "io.sentry.android.gradle" version "4.2.0"
}

def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}

def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
flutterRoot = System.env.FLUTTER_ROOT
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}
}

def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}

def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

android {
ndkVersion "26.0.10792818"

Expand Down Expand Up @@ -104,6 +78,7 @@ android {
}

defaultConfig {

// Include this CMakeLists.txt file in the build pipeline
externalNativeBuild {
cmake {
Expand All @@ -118,13 +93,16 @@ android {
}
}

multiDexEnabled true
vectorDrawables.useSupportLibrary = true

minSdkVersion rootProject.minSdkVersion
targetSdkVersion rootProject.targetSdkVersion

applicationId "org.getlantern.lantern"

ndk {
// Specifies the ABI configurations of native libraries Gradle should build and package with the app.
abiFilters = ["x86_64", "arm64-v8a"]
}

versionCode code

if (project.hasProperty('lanternVersion')) {
Expand All @@ -134,6 +112,7 @@ android {
}
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

vectorDrawables.useSupportLibrary = true
}

externalNativeBuild {
Expand All @@ -144,12 +123,13 @@ android {
}

compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
coreLibraryDesugaringEnabled = true
}

kotlinOptions {
jvmTarget = '11'
jvmTarget = '17'
freeCompilerArgs = ["-Xallow-result-return-type"]
}

Expand Down Expand Up @@ -269,6 +249,7 @@ android {
testOptions {
unitTests.returnDefaultValues = true
}
namespace 'org.getlantern.lantern'
}

def androidArch() {
Expand Down Expand Up @@ -385,6 +366,8 @@ dependencies {
implementation "org.jetbrains.kotlinx:kotlinx-collections-immutable-jvm:0.3.5"
implementation "com.google.protobuf:protobuf-javalite:$protoc_version"

coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:$desugarJdk"

implementation fileTree(dir: "libs", include: "liblantern-${androidArch()}.aar")
// implementation(name:"liblantern-${androidArch()}", ext:'aar')

Expand All @@ -405,8 +388,7 @@ dependencies {

debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.10'

implementation 'androidx.multidex:multidex:2.0.1'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.1'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.7.0'

implementation 'androidx.core:core-ktx:1.10.1'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
Expand Down
17 changes: 16 additions & 1 deletion android/app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,22 @@
-keep class io.lantern.** { *; }

# Gson
-keepnames class com.google.gson.Gson
-keepattributes Signature
-keepattributes *Annotation*
-dontwarn sun.misc.**
-keep class com.google.gson.examples.android.model.** { <fields>; }
-keep class * extends com.google.gson.TypeAdapter
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
-keepclassmembers,allowobfuscation class * {
@com.google.gson.annotations.SerializedName <fields>;
}
-keep,allowobfuscation,allowshrinking class com.google.gson.reflect.TypeToken
-keep,allowobfuscation,allowshrinking class * extends com.google.gson.reflect.TypeToken

# Lifecycle
-keep class androidx.lifecycle.** {*;}

# Safely ignore warnings about other libraries since we are using Gson
-dontwarn com.fasterxml.jackson.**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ class ApplicationTest {
coordinates[1] = Point(248, 929)
coordinates[2] = Point(796, 1520)
coordinates[3] = Point(796, 929)
if (!mDevice.isScreenOn()) {
if (!mDevice.isScreenOn) {
mDevice.wakeUp()
mDevice.swipe(coordinates, 10)
}
Expand Down Expand Up @@ -157,7 +157,7 @@ class ApplicationTest {
}

private inner class JSONParse : AsyncTask<String?, String?, JSONObject>() {
protected override fun doInBackground(vararg params: String?): JSONObject {
override fun doInBackground(vararg params: String?): JSONObject {
Log.d(TAG, "Fetching json from $url")
return JsonParser.getJSONFromUrl(url)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public static JSONObject getJSONFromUrl(String url) {
try {
jObj = new JSONObject(json);
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
Log.e("JSON Parser", "Error parsing data " + e);
}

// return JSON String
Expand Down
3 changes: 1 addition & 2 deletions android/app/src/debug/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.getlantern.lantern">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
Expand Down
1 change: 0 additions & 1 deletion android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="org.getlantern.lantern"
android:installLocation="auto">

<uses-permission android:name="android.permission.INTERNET" />
Expand Down
11 changes: 0 additions & 11 deletions android/app/src/main/kotlin/org/getlantern/lantern/LanternApp.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import android.app.Application
import android.content.Context
import android.os.StrictMode
import androidx.appcompat.app.AppCompatDelegate
import androidx.multidex.MultiDex
import org.getlantern.lantern.model.InAppBilling
import org.getlantern.lantern.model.LanternHttpClient
import org.getlantern.lantern.model.LanternSessionManager
Expand Down Expand Up @@ -40,7 +39,6 @@ open class LanternApp : Application() {

override fun onCreate() {
super.onCreate()
// SentryUtil.enableGoPanicEnrichment(this)

// Necessary to locate a back arrow resource we use from the
// support library. See http://stackoverflow.com/questions/37615470/support-library-vectordrawable-resourcesnotfoundexception
Expand All @@ -59,15 +57,6 @@ open class LanternApp : Application() {
session.resetHasSucceedingProxy()
}

override fun attachBaseContext(base: Context) {
super.attachBaseContext(base)
// this is necessary running earlier versions of Android
// multidex support has to be added manually
// in addition to being enabled in the app build.gradle
// See http://stackoverflow.com/questions/36907916/java-lang-noclassdeffounderror-while-registering-eventbus-in-onstart-method-for
MultiDex.install(this)
}

companion object {
private val TAG = LanternApp::class.java.simpleName
private lateinit var appContext: Context
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class GoTun2SocksProvider(

// Never capture traffic originating from Lantern itself in the VPN.
try {
val ourPackageName = vpnService.getPackageName()
val ourPackageName = vpnService.packageName
builder.addDisallowedApplication(ourPackageName)
} catch (e: PackageManager.NameNotFoundException) {
throw RuntimeException("Unable to exclude Lantern from routes", e)
Expand Down Expand Up @@ -108,7 +108,7 @@ class GoTun2SocksProvider(
Logger.debug(TAG, "Running tun2socks")
if (intf != null) {
Internalsdk.tun2Socks(
intf.getFd().toLong(),
intf.fd.toLong(),
socksAddr,
dnsGrabAddr,
VPN_MTU.toLong(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ class LanternVpnService : VpnService(), Runnable {
if (provider == null) {
Logger.d(TAG, "Using Go tun2socks")
provider = GoTun2SocksProvider(
getPackageManager(),
packageManager,
LanternApp.getSession().splitTunnelingEnabled(),
HashSet(LanternApp.getSession().appsAllowedAccess()),
)
Expand Down
3 changes: 1 addition & 2 deletions android/app/src/play/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="org.getlantern.lantern">
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" tools:node="remove" />
</manifest>
3 changes: 1 addition & 2 deletions android/app/src/profile/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.getlantern.lantern">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
Expand Down
3 changes: 1 addition & 2 deletions android/app/src/sideload/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="org.getlantern.lantern">
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />

<application>
Expand Down
22 changes: 20 additions & 2 deletions android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
buildscript {
ext.kotlin_version = '1.8.21'
ext.kotlin_version = '1.9.23'
ext.signal_version = '2.8.1'
ext.protoc_version = '3.19.3'
ext.desugarJdk = '2.0.3'

repositories {
google()
Expand All @@ -15,7 +16,7 @@ buildscript {

dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.android.tools.build:gradle:7.4.2'
classpath 'com.android.tools.build:gradle:8.4.0-alpha13'
classpath "com.google.protobuf:protobuf-gradle-plugin:0.9.1"
classpath 'com.google.gms:google-services:4.4.0'
classpath("org.jlleitschuh.gradle:ktlint-gradle:11.3.1")
Expand Down Expand Up @@ -53,6 +54,23 @@ allprojects {
mavenCentral()
maven { url 'https://jitpack.io' }
}
// This code fixes a 'namespace not specified' error upgrading AGP to >= 8.x.x.
subprojects {
afterEvaluate { project ->
if (project.hasProperty('android')) {
project.android {
// Replace com.cleveradssolutions.ads.flutter package name with "com.cleveradssolutions.ads"
// This resolves an issue where an incorrect package name appears in the source AndroidManifest.xml
def match = (project.group =~ /com.cleveradssolutions.ads.flutter/)
if (match.size() == 1) {
namespace "com.cleveradssolutions.ads"
} else if (namespace == null) {
namespace project.group
}
}
}
}
}

apply plugin: "org.jlleitschuh.gradle.ktlint"
}
Expand Down
9 changes: 8 additions & 1 deletion android/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
org.gradle.jvmargs=-Xmx4g -Xms256m -XX:MaxMetaspaceSize=1g
org.gradle.vfs.watch=true
org.gradle.parallel=true

android.enableR8.fullMode=true
android.enableResourceOptimizations=true
android.useAndroidX=true
android.enableJetifier=true
kapt.incremental.apt=true
android.enableJetifier=true
android.defaults.buildfeatures.buildconfig=true
android.nonTransitiveRClass=false
android.nonFinalResIds=false
kotlin.jvm.target.validation.mode = IGNORE
2 changes: 1 addition & 1 deletion android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Loading

0 comments on commit 4ed680b

Please sign in to comment.