Skip to content
This repository has been archived by the owner on Oct 18, 2024. It is now read-only.

Commit

Permalink
feat: add support for x86_64 devices/emulators
Browse files Browse the repository at this point in the history
  • Loading branch information
itsaky committed Dec 15, 2023
1 parent e0c455e commit 26fbb79
Show file tree
Hide file tree
Showing 33 changed files with 161 additions and 189 deletions.
4 changes: 0 additions & 4 deletions .idea/compiler.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file removed app/src/arm64-v8a/assets/data/arm64-v8a/busybox
Binary file not shown.
Binary file removed app/src/armeabi-v7a/assets/data/armeabi-v7a/busybox
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import com.google.android.gms.oss.licenses.OssLicensesMenuActivity;
import com.itsaky.androidide.R;
import com.itsaky.androidide.app.IDEActivity;
import com.itsaky.androidide.app.IDEBuildConfigProvider;
import com.itsaky.androidide.app.configuration.IDEBuildConfigProvider;
import com.itsaky.androidide.databinding.ActivityAboutBinding;
import com.itsaky.androidide.databinding.LayoutAboutItemsBinding;
import java.util.ArrayList;
Expand Down
56 changes: 18 additions & 38 deletions app/src/main/java/com/itsaky/androidide/activities/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ import androidx.transition.doOnEnd
import com.blankj.utilcode.util.SizeUtils
import com.google.android.material.transition.MaterialSharedAxis
import com.itsaky.androidide.activities.editor.EditorActivityKt
import com.itsaky.androidide.app.IDEBuildConfigProvider
import com.itsaky.androidide.app.LimitlessIDEActivity
import com.itsaky.androidide.app.configuration.IDEBuildConfigProvider
import com.itsaky.androidide.databinding.ActivityMainBinding
import com.itsaky.androidide.preferences.internal.NO_OPENED_PROJECT
import com.itsaky.androidide.preferences.internal.autoOpenProjects
Expand Down Expand Up @@ -162,9 +162,7 @@ class MainActivity : LimitlessIDEActivity() {
// template list -> template details
// ------- OR -------
// template details -> template list
val setAxisToX =
(previous == SCREEN_TEMPLATE_LIST || previous == SCREEN_TEMPLATE_DETAILS) &&
(screen == SCREEN_TEMPLATE_LIST || screen == SCREEN_TEMPLATE_DETAILS)
val setAxisToX = (previous == SCREEN_TEMPLATE_LIST || previous == SCREEN_TEMPLATE_DETAILS) && (screen == SCREEN_TEMPLATE_LIST || screen == SCREEN_TEMPLATE_DETAILS)

val axis = if (setAxisToX) {
MaterialSharedAxis.X
Expand Down Expand Up @@ -212,15 +210,13 @@ class MainActivity : LimitlessIDEActivity() {
builder.setTitle(string.title_warning)
val view = TextView(this)
view.setPaddingRelative(dp24, dp24, dp24, dp24)
view.text = HtmlCompat.fromHtml(
getString(string.msg_require_install_jdk_and_android_sdk),
view.text = HtmlCompat.fromHtml(getString(string.msg_require_install_jdk_and_android_sdk),
HtmlCompat.FROM_HTML_MODE_COMPACT)
view.movementMethod = LinkMovementMethod.getInstance()
builder.setView(view)
builder.setCancelable(false)
builder.setPositiveButton(android.R.string.ok) { _, _ -> openTerminal() }
builder.setNegativeButton(
android.R.string.cancel) { _, _ -> finishAffinity() }
builder.setNegativeButton(android.R.string.cancel) { _, _ -> finishAffinity() }
builder.setNeutralButton(string.btn_docs) { _, _ -> app.openDocs(); finishAffinity() }
builder.show()
}
Expand All @@ -232,37 +228,22 @@ class MainActivity : LimitlessIDEActivity() {
private fun checkDeviceSupported(): Boolean {
val configProvider = IDEBuildConfigProvider.getInstance()

val supported = if (
configProvider.isArm64v8aBuild()
&& !configProvider.isArm64v8aDevice()
&& configProvider.isArmeabiv7aDevice()
) {
// IDE = 64-bit
// Device = 32-bit
// NOT SUPPORTED
DialogUtils.show64bitOn32bit(this)
false

} else if (
configProvider.isArmeabiv7aBuild()
&& configProvider.isArm64v8aDevice()
) {
// IDE = 32-bit
// Device = 64-bit
// SUPPORTED, but warn the user
if (!prefManager.getBoolean("ide.archConfigWarn.hasShown", false)) {
DialogUtils.show32bitOn64bit(this)
}
true

} else configProvider.supportsBuildFlavor()

if (!supported) {
DialogUtils.showDeviceNotSupported(this)
if (!configProvider.supportsBuildFlavor()) {
DialogUtils.showUnSupportedDevice(this, configProvider.flavorArch.abi,
configProvider.deviceArch.abi)
return false
}

if (configProvider.flavorArch != configProvider.deviceArch) {
// IDE's build flavor is NOT the primary arch of the device
// warn the user
if (!prefManager.getBoolean("ide.archConfig.experimentalWarning.isShown", false)) {
DialogUtils.showExperimentalArchSupportWarning(this, configProvider.flavorArch.abi,
configProvider.deviceArch.abi)
}
}

return supported
return true
}

private fun openLastProject() {
Expand Down Expand Up @@ -302,8 +283,7 @@ class MainActivity : LimitlessIDEActivity() {
private fun askProjectOpenPermission(root: File) {
val builder = DialogUtils.newMaterialDialogBuilder(this)
builder.setTitle(string.title_confirm_open_project)
builder.setMessage(
getString(string.msg_confirm_open_project, root.absolutePath))
builder.setMessage(getString(string.msg_confirm_open_project, root.absolutePath))
builder.setCancelable(false)
builder.setPositiveButton(string.yes) { _, _ -> openProject(root) }
builder.setNegativeButton(string.no, null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/

package com.itsaky.androidide.app
package com.itsaky.androidide.app.configuration

import android.os.Build
import com.google.auto.service.AutoService
Expand All @@ -31,39 +31,32 @@ open class IDEBuildConfigProviderImpl : IDEBuildConfigProvider {
override val buildFlavor: String
get() = BuildConfig.FLAVOR

override val supportedBuildFlavors: Array<String>
get() {
val flavors = mutableListOf<String>()
if (supportedAbis.contains(BuildConfig.FLAVOR_ARM64_V8A)) {
flavors.add(BuildConfig.FLAVOR_ARM64_V8A)
}
if (supportedAbis.contains(BuildConfig.FLAVOR_ARMEABI_V7A)) {
flavors.add(BuildConfig.FLAVOR_ARMEABI_V7A)
}
override val flavorArch: CpuArch
get() = CpuArch.forAbi(buildFlavor)!!

return flavors.toTypedArray()
}
override val deviceArch: CpuArch
get() = CpuArch.forAbi(supportedAbis[0])!!

override val supportedAbis: Array<String>
get() = Build.SUPPORTED_ABIS

override fun isArm64v8aBuild(): Boolean {
return buildFlavor == BuildConfig.FLAVOR_ARM64_V8A
}

override fun isArm64v8aDevice(): Boolean {
return Build.SUPPORTED_64_BIT_ABIS.contains(BuildConfig.FLAVOR_ARM64_V8A)
}

override fun isArmeabiv7aDevice(): Boolean {
return Build.SUPPORTED_32_BIT_ABIS.contains(BuildConfig.FLAVOR_ARMEABI_V7A)
}

override fun isArmeabiv7aBuild(): Boolean {
return buildFlavor == BuildConfig.FLAVOR_ARMEABI_V7A
override val supportedBuildFlavors: Array<String> by lazy {
val flavors = mutableListOf<String>()
if (supportedAbis.contains(BuildConfig.FLAVOR_ARM64_V8A)) {
flavors.add(BuildConfig.FLAVOR_ARM64_V8A)
}
if (supportedAbis.contains(BuildConfig.FLAVOR_X86_64)) {
flavors.add(BuildConfig.FLAVOR_X86_64)
}
if (supportedAbis.contains(BuildConfig.FLAVOR_ARMEABI_V7A)) {
flavors.add(BuildConfig.FLAVOR_ARMEABI_V7A)
}
return@lazy flavors.toTypedArray()
}

override fun supportsBuildFlavor(): Boolean {
return supportedBuildFlavors.contains(buildFlavor)
companion object {
private fun Array<String>?.checkIsPrimaryArch(arch: String): Boolean {
return this?.isNotEmpty() == true && this[0] == arch
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

package com.itsaky.androidide.preferences

import android.content.Context
import androidx.preference.Preference
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.textfield.TextInputLayout
Expand Down Expand Up @@ -70,11 +69,6 @@ private class GradleOptions(
addPreference(GradleCommands())
addPreference(GradleDistrubution())
addPreference(GradleClearCache())
if (IDEBuildConfigProvider.getInstance()
.isArm64v8aBuild() && VERSION.SDK_INT == VERSION_CODES.R
) {
addPreference(TagPointersFix())
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package com.itsaky.androidide.app

import com.google.common.truth.Truth.assertThat
import com.itsaky.androidide.BuildConfig
import com.itsaky.androidide.app.configuration.IDEBuildConfigProviderImpl
import org.junit.Test

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import org.gradle.api.artifacts.Dependency
import org.gradle.api.artifacts.VersionCatalogsExtension
import projectVersionCode

private val flavorsAbis = arrayOf("arm64-v8a", "armeabi-v7a")
private val flavorsAbis = arrayOf("arm64-v8a", "armeabi-v7a", "x86_64")

fun Project.configureAndroidModule(
coreLibDesugDep: Dependency
Expand Down Expand Up @@ -73,7 +73,7 @@ fun Project.configureAndroidModule(
defaultConfig {
ndk {
abiFilters.clear()
abiFilters += arrayOf("armeabi-v7a", "arm64-v8a")
abiFilters += flavorsAbis
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/

package com.itsaky.androidide.app.configuration

/**
* Enum for supported CPU architectures.
*
* @author Akash Yadav
*/
enum class CpuArch(val abi: String) {

/**
* `arm64-v8a` (64-bit).
*/
AARCH64("arm64-v8a"),

/**
* `x86_64` (64-bit).
*/
X86_64("x86_64"),

/**
* `armeabi-v7a` flavor (32-bit).
*/
ARM("armeabi-v7a");

companion object {

/**
* Get the [CpuArch] for the given ABI.
*/
@JvmStatic
fun forAbi(abi: String): CpuArch? {
return entries.firstOrNull { it.abi == abi }
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/

package com.itsaky.androidide.app
package com.itsaky.androidide.app.configuration

import com.itsaky.androidide.utils.ServiceLoader

Expand All @@ -31,40 +31,60 @@ interface IDEBuildConfigProvider {
*/
val buildFlavor: String

/**
* Get the [CpuArch] for the build flavor.
*/
val flavorArch: CpuArch

/**
* The build flavors which can be installed on the current device.
*/
val supportedBuildFlavors: Array<String>

/**
* Get the primary CPU architecture of the device.
*/
val deviceArch: CpuArch

/**
* The supported CPU architectures of the device.
*/
val supportedAbis: Array<String>

/**
* @return Whether this build is the 64-bit variant of the IDE.
* @return Whether this build is the `arm64-v8a` variant of the IDE.
*/
fun isArm64v8aBuild(): Boolean
fun isArm64v8aBuild(): Boolean = flavorArch == CpuArch.AARCH64

/**
* @return Whether the device supports `arm64-v8a` instructions.
*/
fun isArm64v8aDevice() : Boolean
fun isArm64v8aDevice(): Boolean = deviceArch == CpuArch.AARCH64

/**
* @return Whether this build is the 32-bit variant of the IDE.
*/
fun isArmeabiv7aBuild(): Boolean
fun isArmeabiv7aBuild(): Boolean = flavorArch == CpuArch.ARM

/**
* @return Whether the device supports `armeabi-v7a` instructions.
*/
fun isArmeabiv7aDevice() : Boolean
fun isArmeabiv7aDevice(): Boolean = deviceArch == CpuArch.ARM

/**
* @return Whether this build is the `x86_64` variant of the IDE.
*/
fun isX86_64Build(): Boolean = flavorArch == CpuArch.X86_64

/**
* @return Whether the device supports `x86_64` instructions.
*/
fun isX86_64Device(): Boolean = deviceArch == CpuArch.X86_64

/**
* @return Whether the IDE can be run on the device's CPU arch.
*/
fun supportsBuildFlavor() : Boolean
fun supportsBuildFlavor(): Boolean = supportedBuildFlavors.contains(buildFlavor)

companion object {

Expand Down
Loading

0 comments on commit 26fbb79

Please sign in to comment.