Skip to content

Commit

Permalink
Merge pull request #2 from tytydraco/main
Browse files Browse the repository at this point in the history
update
  • Loading branch information
ghost58400 committed Jul 14, 2023
2 parents 20ace63 + 76f040b commit 1824cd2
Show file tree
Hide file tree
Showing 18 changed files with 161 additions and 318 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,4 @@ We also have a Telegram server here: https://t.me/ladb_support.

# Privacy Policy

LADB does not send any device data outside of the app. Your data is not collected or processed.
LADB does not send any device data outside the app. Your data is not collected or processed.
20 changes: 10 additions & 10 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ android {
applicationId "com.draco.ladb"
minSdk 26
targetSdk 33
versionCode 39
versionName "2.1"
versionCode 43
versionName "2.3.1"

ndk {
abiFilters 'arm64-v8a', 'armeabi-v7a', 'x86', 'x86_64'
Expand Down Expand Up @@ -57,16 +57,16 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4'

implementation 'androidx.core:core-ktx:1.9.0'
implementation 'androidx.appcompat:appcompat:1.5.1'
implementation 'androidx.core:core-ktx:1.10.1'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'androidx.preference:preference-ktx:1.2.0'
implementation 'androidx.fragment:fragment-ktx:1.5.3'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.5.1'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1'
implementation 'androidx.fragment:fragment-ktx:1.6.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.1'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.1'

implementation 'com.github.javiersantos:PiracyChecker:1.2.8'

implementation 'com.google.android.material:material:1.6.1'
implementation 'com.google.android.gms:play-services-oss-licenses:17.0.0'
implementation 'com.google.android.material:material:1.9.0'
implementation 'com.google.android.gms:play-services-oss-licenses:17.0.1'
}
10 changes: 0 additions & 10 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,7 @@
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />

<data android:mimeType="text/x-sh" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
<activity
android:name=".views.PairActivity"
android:label="@string/pair" />
<activity
android:name=".views.HelpActivity"
android:label="@string/more" />
Expand Down
39 changes: 11 additions & 28 deletions app/src/main/java/com/draco/ladb/utils/ADB.kt
Original file line number Diff line number Diff line change
Expand Up @@ -89,23 +89,21 @@ class ADB(private val context: Context) {
/* Only do wireless debugging steps on compatible versions */
if (secureSettingsGranted) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && !isWirelessDebuggingEnabled()) {
debug("Enabling wireless debugging...")
Settings.Global.putInt(
context.contentResolver,
"adb_wifi_enabled",
1
)

Thread.sleep(3_000)
Thread.sleep(2_000)
} else if (!isUSBDebuggingEnabled()) {
debug("Enabling USB debugging...")
Settings.Global.putInt(
context.contentResolver,
Settings.Global.ADB_ENABLED,
1
)

Thread.sleep(3_000)
Thread.sleep(2_000)
}
}

Expand All @@ -128,23 +126,19 @@ class ADB(private val context: Context) {
}
}

debug("Starting ADB server...")
adb(false, listOf("start-server")).waitFor()
debug("Waiting for device to connect...")
debug("This may take up to 2 minutes")
val waitProcess = adb(false, listOf("wait-for-device")).waitFor(2, TimeUnit.MINUTES)
debug("This may take a minute")
val waitProcess = adb(false, listOf("wait-for-device")).waitFor(1, TimeUnit.MINUTES)
if (!waitProcess) {
debug("Could not detect any devices")
debug("Fix 1) Toggle Wi-Fi or reboot")
debug("Fix 2) Re-enter pairing information (More -> Factory Reset)")
debug("To try again, restart the server (More -> Restart)")
debug("Your device didn't connect to LADB")
debug("If a reboot doesn't work, please contact support")

tryingToPair = false
return false
}
}

debug("Shelling into device")
shellProcess = if (autoShell) {
val argList = if (Build.SUPPORTED_ABIS[0] == "arm64-v8a")
listOf("-t", "1", "shell")
Expand Down Expand Up @@ -216,6 +210,11 @@ class ADB(private val context: Context) {
/* Continue once finished pairing (or 10s elapses) */
pairShell.waitFor(10, TimeUnit.SECONDS)
pairShell.destroyForcibly().waitFor()

val killShell = adb(false, listOf("kill-server"))
killShell.waitFor(3, TimeUnit.SECONDS)
killShell.destroyForcibly()

return pairShell.exitValue() == 0
}

Expand Down Expand Up @@ -250,22 +249,6 @@ class ADB(private val context: Context) {
return processBuilder.start()!!
}

/**
* Execute a script
*/
fun sendScript(code: String) {
/* Store script locally */
val internalScript = File(scriptPath).apply {
bufferedWriter().use {
it.write(code)
}
deleteOnExit()
}

/* Execute the script here */
sendToShellProcess("sh ${internalScript.absolutePath}")
}

/**
* Send commands directly to the shell process
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,13 +109,8 @@ class MainActivityViewModel(application: Application) : AndroidViewModel(applica
fun needsToPair(): Boolean {
val context = getApplication<Application>().applicationContext

if (!sharedPreferences.getBoolean(context.getString(R.string.paired_key), false) &&
(Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
) {
return true
}

return false
return !sharedPreferences.getBoolean(context.getString(R.string.paired_key), false) &&
(Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
}

fun setPairedBefore(value: Boolean) {
Expand All @@ -125,31 +120,6 @@ class MainActivityViewModel(application: Application) : AndroidViewModel(applica
}
}

/**
* Return the contents of the script from the intent
*/
fun getScriptFromIntent(intent: Intent): String? {
val context = getApplication<Application>().applicationContext

return when (intent.type) {
"text/x-sh" -> {
val extra = if (Build.VERSION.SDK_INT >= 33) {
intent.getParcelableExtra(Intent.EXTRA_STREAM, Parcelable::class.java).toString()
} else {
intent.getParcelableExtra<Parcelable?>(Intent.EXTRA_STREAM).toString()
}

val uri = Uri.parse(extra)
context.contentResolver.openInputStream(uri)?.bufferedReader().use {
it?.readText()
}
}

"text/plain" -> intent.getStringExtra(Intent.EXTRA_TEXT)
else -> null
}
}

/**
* Read the content of the ABD output file
*/
Expand Down
116 changes: 69 additions & 47 deletions app/src/main/java/com/draco/ladb/views/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.draco.ladb.views

import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.view.KeyEvent
import android.view.Menu
Expand All @@ -12,14 +13,19 @@ import android.view.inputmethod.InputMethodManager
import android.widget.ScrollView
import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.FileProvider
import androidx.core.content.edit
import androidx.lifecycle.lifecycleScope
import androidx.preference.PreferenceManager
import com.draco.ladb.BuildConfig
import com.draco.ladb.R
import com.draco.ladb.databinding.ActivityMainBinding
import com.draco.ladb.viewmodels.MainActivityViewModel
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.snackbar.Snackbar
import com.google.android.material.textfield.TextInputEditText
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlin.system.exitProcess
Expand All @@ -28,36 +34,24 @@ class MainActivity : AppCompatActivity() {
private val viewModel: MainActivityViewModel by viewModels()
private lateinit var binding: ActivityMainBinding

private lateinit var pairDialog: MaterialAlertDialogBuilder

private var lastCommand = ""

private var bookmarkGetResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
val text = it.data?.getStringExtra(Intent.EXTRA_TEXT) ?: return@registerForActivityResult
binding.command.setText(text)
}

private var pairGetResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
val port = result.data?.getStringExtra("port") ?: ""
val code = result.data?.getStringExtra("code") ?: ""

viewModel.adb.debug("Trying to pair...")
lifecycleScope.launch(Dispatchers.IO) {
val success = viewModel.adb.pair(port, code)

if (success) {
viewModel.setPairedBefore(true)
viewModel.startADBServer()
} else {
/* Failed; try again! */
viewModel.setPairedBefore(false)
viewModel.adb.debug("Failed to pair! Trying again...")
runOnUiThread { pairAndStart() }
}

viewModel.isPairing.postValue(false)
}
}

private fun setupUI() {
pairDialog = MaterialAlertDialogBuilder(this)
.setTitle(R.string.pair_title)
.setCancelable(false)
.setView(R.layout.dialog_pair)
.setPositiveButton(R.string.pair, null)
.setNegativeButton(R.string.help, null)
.setNeutralButton(R.string.skip, null)

binding.command.setOnKeyListener { _, keyCode, keyEvent ->
if (keyCode == KeyEvent.KEYCODE_ENTER && keyEvent.action == KeyEvent.ACTION_DOWN) {
sendCommandToADB()
Expand Down Expand Up @@ -117,23 +111,23 @@ class MainActivity : AppCompatActivity() {

/* Prepare progress bar, pairing latch, and script executing */
viewModel.adb.started.observe(this) { started ->
if (started == true) {
lifecycleScope.launch(Dispatchers.IO) {
runOnUiThread { setReadyForInput(true) }
executeScriptFromIntent()
}
} else {
runOnUiThread { setReadyForInput(false) }
return@observe
}
setReadyForInput(started == true)
}
}

private fun pairAndStart() {
if (viewModel.needsToPair()) {
viewModel.adb.debug("Requesting pairing information")
viewModel.isPairing.value = true
pairGetResult.launch(Intent(this, PairActivity::class.java))
askToPair { thisPairSuccess ->
if (thisPairSuccess) {
viewModel.setPairedBefore(true)
viewModel.startADBServer()
} else {
/* Failed; try again! */
viewModel.adb.debug("Failed to pair! Trying again...")
runOnUiThread { pairAndStart() }
}
}
} else {
viewModel.startADBServer()
}
Expand All @@ -153,22 +147,50 @@ class MainActivity : AppCompatActivity() {
}

/**
* Execute a script from the main intent if one was given
* Ask the user to pair
*/
private fun executeScriptFromIntent() {
if (viewModel.getScriptFromIntent(intent) == null)
return

val code = viewModel.getScriptFromIntent(intent) ?: return

/* Invalidate intent */
intent.type = ""

Snackbar.make(binding.output, getString(R.string.snackbar_file_opened), Snackbar.LENGTH_SHORT)
.setAction(getString(R.string.dismiss)) {}
private fun askToPair(callback: ((Boolean) -> (Unit))? = null) {
pairDialog
.create()
.apply {
setOnShowListener {
getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener {
val port = findViewById<TextInputEditText>(R.id.port)!!.text.toString()
val code = findViewById<TextInputEditText>(R.id.code)!!.text.toString()
dismiss()

lifecycleScope.launch(Dispatchers.IO) {
viewModel.adb.debug("Trying to pair...")
val success = viewModel.adb.pair(port, code)
callback?.invoke(success)
}
}

getButton(AlertDialog.BUTTON_NEGATIVE).setOnClickListener {
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.tutorial_url)))
try {
startActivity(intent)
} catch (e: Exception) {
e.printStackTrace()
Snackbar.make(
binding.output,
getString(R.string.snackbar_intent_failed),
Snackbar.LENGTH_SHORT
)
.show()
}
}

getButton(AlertDialog.BUTTON_NEUTRAL).setOnClickListener {
PreferenceManager.getDefaultSharedPreferences(context).edit(true) {
putBoolean(getString(R.string.auto_shell_key), false)
}
dismiss()
callback?.invoke(true)
}
}
}
.show()

viewModel.adb.sendScript(code)
}

override fun onOptionsItemSelected(item: MenuItem): Boolean {
Expand Down
Loading

0 comments on commit 1824cd2

Please sign in to comment.