diff --git a/NeoLang/.gitignore b/NeoLang/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/NeoLang/.gitignore @@ -0,0 +1 @@ +/build diff --git a/NeoLang/build.gradle b/NeoLang/build.gradle new file mode 100644 index 0000000..b8ccbda --- /dev/null +++ b/NeoLang/build.gradle @@ -0,0 +1,32 @@ +apply plugin: 'java-library' +apply plugin: 'kotlin' + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version" +} + +sourceCompatibility = "1.7" +targetCompatibility = "1.7" +buildscript { + ext.kotlin_version = '1.1.3' + repositories { + mavenCentral() + } + dependencies { + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} +repositories { + mavenCentral() +} +compileKotlin { + kotlinOptions { + jvmTarget = "1.8" + } +} +compileTestKotlin { + kotlinOptions { + jvmTarget = "1.8" + } +} diff --git a/NeoLang/example/main.neo b/NeoLang/example/main.neo new file mode 100644 index 0000000..00f3c5c --- /dev/null +++ b/NeoLang/example/main.neo @@ -0,0 +1,4 @@ +NeoLang { + version : 1 + x-letter : ${NeoLang@version} >= 2 +} diff --git a/NeoLang/src/main/java/io/neolang/Version.kt b/NeoLang/src/main/java/io/neolang/Version.kt new file mode 100644 index 0000000..acf806d --- /dev/null +++ b/NeoLang/src/main/java/io/neolang/Version.kt @@ -0,0 +1,10 @@ +package io.neolang + +/** + * @author kiva + */ +object Version { + const val MAJOR = 0 + const val MINOR = 1 + const val PATCH = 0 +} \ No newline at end of file diff --git a/NeoLang/src/main/java/io/neolang/token/Token.kt b/NeoLang/src/main/java/io/neolang/token/Token.kt new file mode 100644 index 0000000..59abc5c --- /dev/null +++ b/NeoLang/src/main/java/io/neolang/token/Token.kt @@ -0,0 +1,10 @@ +package io.neolang.token + +/** + * @author kiva + */ +class Token { + lateinit var type: TokenType + lateinit var value: Any + lateinit var nextToken: Token +} \ No newline at end of file diff --git a/NeoLang/src/main/java/io/neolang/token/TokenType.kt b/NeoLang/src/main/java/io/neolang/token/TokenType.kt new file mode 100644 index 0000000..28b0438 --- /dev/null +++ b/NeoLang/src/main/java/io/neolang/token/TokenType.kt @@ -0,0 +1,40 @@ +package io.neolang.token + +/** + * @author kiva + */ +enum class TokenType { + TYPE_IDENTIFIER, + TYPE_STRING, + TYPE_INTEGER, + TYPE_BOOLEAN, + + KEYWORD_DOLLAR, /* $ */ + KEYWORD_USE /* @ */, + + OPERATOR_BEGIN, + OPT_ADD, /* + */ + OPT_SUB, /* - */ + OPT_NAV, /* - (负号) */ + OPT_MUL, /* * */ + OPT_DIV, /* / */ + OPT_MOD, /* % */ + OPT_XOR, /* ^ */ + OPT_AND, /* & */ + OPT_OR, /* | */ + LEFT_SHIFT, /* << */ + RIGHT_SHIFT, /* >> */ + OPERATOR_END, + + LOGICAL_OPERATOR_BEGIN, + OPT_LAND, /* && */ + OPT_LOR, /* || */ + OPT_LE, /* <= */ + OPT_LT, /* < */ + OPT_GE, /* >= */ + OPT_GT, /* > */ + OPT_EQ, /* == */ + OPT_NEQ, /* != */ + OPT_NOT, /* ! */ + LOGICAL_OPERATOR_END, +} \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 31cf3eb..fa776e8 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -17,8 +17,8 @@ android { applicationId "io.neoterm" minSdkVersion 21 targetSdkVersion 25 - versionCode 8 - versionName "1.1.6" + versionCode 9 + versionName "1.1.7" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" resConfigs "zh" externalNativeBuild { diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 1dc7dc7..5a1dafd 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -24,6 +24,10 @@ # hide the original source file name. #-renamesourcefileattribute SourceFile +-dontpreverify +-printmapping proguardMapping.txt + + -keep class io.neoterm.backend.JNI { *; } @@ -51,14 +55,14 @@ # (java.lang.Throwable); #} -#rxjava --dontwarn rx.** -#-keep class rx.** { *; } - #skf4j -dontwarn org.slf4j.** -dontwarn sun.misc.** + +# RxJava +#-keep class rx.** { *; } +-dontwarn rx.** -keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* { long producerIndex; long consumerIndex; @@ -69,3 +73,24 @@ -keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef { rx.internal.util.atomic.LinkedQueueNode consumerNode; } + + +# Parcelable +-keep class * implements android.os.Parcelable { + public static final android.os.Parcelable$Creator *; +} +-keepclassmembers class * implements android.os.Parcelable { + public ; + private ; +} + +# Serializable +-keepclassmembers class * implements java.io.Serializable { + static final long serialVersionUID; + private static final java.io.ObjectStreamField[] serialPersistentFields; + private void writeObject(java.io.ObjectOutputStream); + private void readObject(java.io.ObjectInputStream); + java.lang.Object writeReplace(); + java.lang.Object readResolve(); +} + diff --git a/app/src/main/java/io/neoterm/customize/setup/BaseFileInstaller.java b/app/src/main/java/io/neoterm/customize/setup/BaseFileInstaller.java index b093ace..c671ef4 100644 --- a/app/src/main/java/io/neoterm/customize/setup/BaseFileInstaller.java +++ b/app/src/main/java/io/neoterm/customize/setup/BaseFileInstaller.java @@ -11,10 +11,9 @@ import android.util.Pair; import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; -import java.io.InputStream; +import java.io.IOException; import java.io.InputStreamReader; import java.net.HttpURLConnection; -import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; @@ -24,8 +23,8 @@ import java.util.zip.ZipInputStream; import io.neoterm.R; import io.neoterm.backend.EmulatorDebug; +import io.neoterm.preference.NeoPreference; import io.neoterm.preference.NeoTermPath; -import io.neoterm.utils.FileUtils; public final class BaseFileInstaller { public interface ResultListener { @@ -64,8 +63,9 @@ public final class BaseFileInstaller { final byte[] buffer = new byte[8096]; final List> symlinks = new ArrayList<>(50); - final URL zipUrl = determineZipUrl(); - HttpURLConnection connection = (HttpURLConnection) zipUrl.openConnection(); + HttpURLConnection connection = openBaseFileConnection(); + connection.setConnectTimeout(8000); + connection.setReadTimeout(8000); totalBytes = connection.getContentLength(); try (ZipInputStream zipInput = new ZipInputStream(connection.getInputStream())) { @@ -171,12 +171,22 @@ public final class BaseFileInstaller { }.start(); } - private static URL determineZipUrl() throws MalformedURLException { - String archName = determineArchName(); - String baseUrl = NeoTermPath.INSTANCE.getSERVER_BOOT_URL(); - return new URL(baseUrl + "/" + archName + ".zip"); + private static HttpURLConnection openBaseFileConnection() throws IOException { + String arch = determineArchName(); + String baseUrl = NeoTermPath.INSTANCE.getDEFAULT_SOURCE(); + + // Use the same source + NeoPreference.INSTANCE.store(R.string.key_package_source, baseUrl); + + return (HttpURLConnection) new URL(baseUrl + "/boot/" + arch + ".zip").openConnection(); } +// private static URL determineZipUrl() throws MalformedURLException { +// String archName = determineArchName(); +// String baseUrl = NeoTermPath.INSTANCE.getSERVER_BOOT_URL(); +// return new URL(baseUrl + "/" + archName + ".zip"); +// } + private static String determineArchName() { for (String androidArch : Build.SUPPORTED_ABIS) { switch (androidArch) { @@ -186,8 +196,8 @@ public final class BaseFileInstaller { return "arm"; case "x86_64": return "x86_64"; - case "x86": - return "i686"; +// case "x86": +// return "i686"; } } throw new RuntimeException("Unable to determine arch from Build.SUPPORTED_ABIS = " + diff --git a/app/src/main/java/io/neoterm/preference/NeoPermission.kt b/app/src/main/java/io/neoterm/preference/NeoPermission.kt index 7f768e1..ca82e69 100644 --- a/app/src/main/java/io/neoterm/preference/NeoPermission.kt +++ b/app/src/main/java/io/neoterm/preference/NeoPermission.kt @@ -3,6 +3,7 @@ package io.neoterm.preference import android.Manifest import android.app.Activity import android.app.AlertDialog +import android.content.ActivityNotFoundException import android.content.DialogInterface import android.content.pm.PackageManager import android.os.Build @@ -28,17 +29,23 @@ object NeoPermission { Manifest.permission.READ_CONTACTS)) { AlertDialog.Builder(context).setMessage("需要存储权限来访问存储设备上的文件") .setPositiveButton(android.R.string.ok, { _: DialogInterface, _: Int -> - ActivityCompat.requestPermissions(context, - arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), - requestCode) + doRequestPermission(context, requestCode) }) .show() } else { - ActivityCompat.requestPermissions(context, - arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), - requestCode) + doRequestPermission(context, requestCode) } } } + + private fun doRequestPermission(context: Activity, requestCode: Int) { + try { + ActivityCompat.requestPermissions(context, + arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), + requestCode) + } catch (ignore: ActivityNotFoundException) { + // for MIUI, we ignore it. + } + } } \ No newline at end of file diff --git a/app/src/main/java/io/neoterm/preference/NeoTermPath.kt b/app/src/main/java/io/neoterm/preference/NeoTermPath.kt index d91d6f5..0936628 100644 --- a/app/src/main/java/io/neoterm/preference/NeoTermPath.kt +++ b/app/src/main/java/io/neoterm/preference/NeoTermPath.kt @@ -22,8 +22,8 @@ object NeoTermPath { const val SOURCE_FILE = "$USR_PATH/etc/apt/sources.list" const val PACKAGE_LIST_DIR = "$USR_PATH/var/lib/apt/lists" - private const val RELEASE_SOURCE = "https://mirrors.geekpie.org/neoterm" - private const val DEBUG_SOURCE = "http://192.243.117.135" + const val RELEASE_SOURCE = "https://mirrors.geekpie.org/neoterm" + const val DEBUG_SOURCE = "http://neoterm.studio" val DEFAULT_SOURCE: String val SERVER_BASE_URL: String @@ -32,6 +32,6 @@ object NeoTermPath { init { DEFAULT_SOURCE = if (BuildConfig.DEBUG) DEBUG_SOURCE else RELEASE_SOURCE SERVER_BASE_URL = DEFAULT_SOURCE - SERVER_BOOT_URL = "${SERVER_BASE_URL}/boot" + SERVER_BOOT_URL = "$SERVER_BASE_URL/boot" } } \ No newline at end of file diff --git a/app/src/main/java/io/neoterm/ui/pm/PackageManagerActivity.kt b/app/src/main/java/io/neoterm/ui/pm/PackageManagerActivity.kt index b85fc84..a546089 100644 --- a/app/src/main/java/io/neoterm/ui/pm/PackageManagerActivity.kt +++ b/app/src/main/java/io/neoterm/ui/pm/PackageManagerActivity.kt @@ -30,6 +30,7 @@ import io.neoterm.preference.NeoTermPath import io.neoterm.ui.pm.adapter.PackageAdapter import io.neoterm.ui.pm.model.PackageModel import io.neoterm.utils.FileUtils +import io.neoterm.utils.PackageUtils import io.neoterm.view.TerminalDialog import java.io.File import java.net.URL @@ -171,9 +172,7 @@ class PackageManagerActivity : AppCompatActivity(), SearchView.OnQueryTextListen private fun changeSourceInternal(source: String) { NeoPreference.store(R.string.key_package_source, source) - - val sourceFile = File(NeoTermPath.SOURCE_FILE) - FileUtils.writeFile(sourceFile, generateSourceFile(source).toByteArray()) + PackageUtils.syncSource() executeAptUpdate() } @@ -220,15 +219,6 @@ class PackageManagerActivity : AppCompatActivity(), SearchView.OnQueryTextListen }.start() } - private fun generateSourceFile(source: String): String { - return StringBuilder().append("# Generated by NeoTerm-Preference\n") - .append("deb ") - .append(source) - .append(" stable main") - .append("\n") - .toString() - } - private fun filter(models: List, query: String?): List { val filteredModelList = ArrayList() if (query != null) { diff --git a/app/src/main/java/io/neoterm/ui/setup/SetupActivity.kt b/app/src/main/java/io/neoterm/ui/setup/SetupActivity.kt index ecb970e..95d9e83 100644 --- a/app/src/main/java/io/neoterm/ui/setup/SetupActivity.kt +++ b/app/src/main/java/io/neoterm/ui/setup/SetupActivity.kt @@ -21,6 +21,7 @@ import io.neoterm.customize.pm.NeoPackageManagerUtils import io.neoterm.customize.setup.BaseFileInstaller import io.neoterm.preference.NeoPreference import io.neoterm.preference.NeoTermPath +import io.neoterm.utils.PackageUtils import io.neoterm.view.TerminalDialog import java.util.* @@ -92,6 +93,7 @@ class SetupActivity : AppCompatActivity() { resultListener = BaseFileInstaller.ResultListener { error -> if (error == null) { setResult(Activity.RESULT_OK) + PackageUtils.syncSource() executeAptUpdate() } else { AlertDialog.Builder(this@SetupActivity) @@ -100,6 +102,7 @@ class SetupActivity : AppCompatActivity() { .setNegativeButton(R.string.use_system_shell, { _, _ -> setResult(Activity.RESULT_CANCELED) nextButton.visibility = View.VISIBLE + finish() }) .setPositiveButton(R.string.retry, { dialog, _ -> dialog.dismiss() @@ -156,10 +159,12 @@ class SetupActivity : AppCompatActivity() { val packageName = item.title val pm = NeoPackageManager.get() val packageInfo = pm.getPackageInfo(packageName) - val packageDesc = packageInfo.description - toast.cancel() - toast.setText(packageDesc) - toast.show() + if (packageInfo != null) { + val packageDesc = packageInfo.description + toast.cancel() + toast.setText(packageDesc) + toast.show() + } } override fun onBubbleDeselected(item: PickerItem) { diff --git a/app/src/main/java/io/neoterm/utils/PackageUtils.kt b/app/src/main/java/io/neoterm/utils/PackageUtils.kt new file mode 100644 index 0000000..37e3a27 --- /dev/null +++ b/app/src/main/java/io/neoterm/utils/PackageUtils.kt @@ -0,0 +1,26 @@ +package io.neoterm.utils + +import io.neoterm.R +import io.neoterm.preference.NeoPreference +import io.neoterm.preference.NeoTermPath +import java.io.File + +/** + * @author kiva + */ +object PackageUtils { + fun syncSource() { + val source = NeoPreference.loadString(R.string.key_package_source, NeoTermPath.DEFAULT_SOURCE) + val sourceFile = File(NeoTermPath.SOURCE_FILE) + FileUtils.writeFile(sourceFile, generateSourceFile(source).toByteArray()) + } + + private fun generateSourceFile(source: String): String { + return StringBuilder().append("# Generated by NeoTerm-Preference\n") + .append("deb ") + .append(source) + .append(" stable main") + .append("\n") + .toString() + } +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index db5559a..8f3cf9f 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1 @@ -include ':app', ':chrome-tabs' +include ':app', ':chrome-tabs', ':NeoLang'