diff --git a/app/release/app-release.apk b/app/release/app-release.apk index b21427d..69e1fe5 100644 Binary files a/app/release/app-release.apk and b/app/release/app-release.apk differ diff --git a/app/src/main/java/com/legendsayantan/adbtools/DebloatActivity.kt b/app/src/main/java/com/legendsayantan/adbtools/DebloatActivity.kt index 50ff3c0..c3ee4c3 100644 --- a/app/src/main/java/com/legendsayantan/adbtools/DebloatActivity.kt +++ b/app/src/main/java/com/legendsayantan/adbtools/DebloatActivity.kt @@ -208,8 +208,7 @@ class DebloatActivity : AppCompatActivity() { onFailure: () -> Unit ) { try { - val url = - URL("https://cdn.jsdelivr.net/gh/Universal-Debloater-Alliance/universal-android-debloater-next-generation@main/resources/assets/uad_lists.json") + val url = URL(getString(R.string.url_uad_lists)) GlobalScope.launch(Dispatchers.IO) { try { // Read the JSON content from the URL @@ -306,7 +305,6 @@ class DebloatActivity : AppCompatActivity() { val allApps = output.replace("package:", "").split("\n") loadApps { installed -> val uninstalled = allApps.filter { !installed.contains(it) } - println(uninstalled) runOnUiThread { val appsView = RecyclerView(activityContext) val dialog = MaterialAlertDialogBuilder(activityContext) @@ -350,6 +348,6 @@ class DebloatActivity : AppCompatActivity() { } companion object{ - val FILENAME_DATABASE: String = "debloat-list.json" + const val FILENAME_DATABASE: String = "debloat-list.json" } } \ No newline at end of file diff --git a/app/src/main/java/com/legendsayantan/adbtools/LookbackActivity.kt b/app/src/main/java/com/legendsayantan/adbtools/LookbackActivity.kt index fe8c323..aff05da 100644 --- a/app/src/main/java/com/legendsayantan/adbtools/LookbackActivity.kt +++ b/app/src/main/java/com/legendsayantan/adbtools/LookbackActivity.kt @@ -59,17 +59,21 @@ class LookbackActivity : AppCompatActivity() { "Installed Successfully.", Toast.LENGTH_SHORT ).show() - } else { - Toast.makeText( - applicationContext, - "Failure: ${output}", - Toast.LENGTH_SHORT - ).show() } cacheFile.delete() } } } + + override fun onCommandError(error: String) { + Handler(mainLooper).post { + Toast.makeText( + applicationContext, + "Failure: $error", + Toast.LENGTH_SHORT + ).show() + } + } }) } diff --git a/app/src/main/java/com/legendsayantan/adbtools/MainActivity.kt b/app/src/main/java/com/legendsayantan/adbtools/MainActivity.kt index 75c497a..3b25375 100644 --- a/app/src/main/java/com/legendsayantan/adbtools/MainActivity.kt +++ b/app/src/main/java/com/legendsayantan/adbtools/MainActivity.kt @@ -28,8 +28,6 @@ import com.google.android.material.switchmaterial.SwitchMaterial import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputLayout import com.legendsayantan.adbtools.lib.ShizukuRunner -import com.legendsayantan.adbtools.lib.Utils -import com.legendsayantan.adbtools.lib.Utils.Companion.initialiseNotiChannel import com.legendsayantan.adbtools.lib.Utils.Companion.initialiseStatusBar import com.legendsayantan.adbtools.services.SoundMasterService import java.util.UUID @@ -122,19 +120,20 @@ class MainActivity : AppCompatActivity() { } } } - cardShell.setOnClickListener { openShell() } + cardShell.setOnClickListener { localShell() } cardIntentShell.setOnClickListener { intentShell() } } - private fun openShell() { + private fun localShell() { val dialog = MaterialAlertDialogBuilder(this) - dialog.setTitle("ADB Shell") + dialog.setTitle(getString(R.string.localshell)) val scrollContainer = ScrollView(this) val layout = LinearLayout(this) layout.orientation = LinearLayout.VERTICAL layout.setPadding(30, 25, 30, 15) val commandOut = TextView(this) val commandBar = LinearLayout(this) + commandOut.typeface = resources.getFont(R.font.consolas) commandBar.orientation = LinearLayout.HORIZONTAL commandBar.gravity = Gravity.CENTER val editText = EditText(this) @@ -158,6 +157,12 @@ class MainActivity : AppCompatActivity() { btn.isEnabled = done } } + + override fun onCommandError(error: String) { + runOnUiThread { + commandOut.text = "ERROR:\n$error" + } + } }) editText.selectAll() } @@ -174,9 +179,9 @@ class MainActivity : AppCompatActivity() { private fun intentShell(){ val prefs = getSharedPreferences("execution", MODE_PRIVATE) if(prefs.getString("key",null)==null){ - prefs.edit().putString("key",UUID.randomUUID().toString()).apply() + prefs.edit().putString("key",UUID.randomUUID().toString().replace("-","")).apply() } - val key = prefs.getString("key",null) + val key = prefs.getString("key",null)?.replace("-","") val layout = LinearLayout(this).apply { setPadding(60,0,60,0) } diff --git a/app/src/main/java/com/legendsayantan/adbtools/MixedAudioActivity.kt b/app/src/main/java/com/legendsayantan/adbtools/MixedAudioActivity.kt index 8d37451..b1936c1 100644 --- a/app/src/main/java/com/legendsayantan/adbtools/MixedAudioActivity.kt +++ b/app/src/main/java/com/legendsayantan/adbtools/MixedAudioActivity.kt @@ -224,6 +224,13 @@ class MixedAudioActivity : AppCompatActivity() { reloadApps() } } + + override fun onCommandError(error: String) { + runOnUiThread { + Toast.makeText(this@MixedAudioActivity, "Error: $error", Toast.LENGTH_SHORT).show() + dialog.dismiss() + } + } }) } }) diff --git a/app/src/main/java/com/legendsayantan/adbtools/SoundMasterActivity.kt b/app/src/main/java/com/legendsayantan/adbtools/SoundMasterActivity.kt index 4e8aea0..2b96247 100644 --- a/app/src/main/java/com/legendsayantan/adbtools/SoundMasterActivity.kt +++ b/app/src/main/java/com/legendsayantan/adbtools/SoundMasterActivity.kt @@ -7,6 +7,7 @@ import android.content.Intent import android.media.projection.MediaProjectionManager import android.os.Bundle import android.os.Handler +import android.view.Gravity import android.view.View import android.widget.ImageView import android.widget.Space @@ -20,7 +21,6 @@ import androidx.recyclerview.widget.RecyclerView import com.google.android.material.card.MaterialCardView import com.legendsayantan.adbtools.adapters.VolumeBarAdapter import com.legendsayantan.adbtools.data.AudioOutputBase -import com.legendsayantan.adbtools.data.AudioOutputKey import com.legendsayantan.adbtools.dialog.AppSelectionDialog import com.legendsayantan.adbtools.dialog.OutputSelectionDialog import com.legendsayantan.adbtools.lib.ShizukuRunner @@ -28,7 +28,6 @@ import com.legendsayantan.adbtools.lib.Utils.Companion.initialiseStatusBar import com.legendsayantan.adbtools.services.SoundMasterService import com.legendsayantan.adbtools.services.SoundMasterService.Companion.prepareGetAudioDevices import java.io.File -import java.io.FileNotFoundException import java.util.Timer import kotlin.concurrent.timerTask @@ -44,7 +43,11 @@ class SoundMasterActivity : AppCompatActivity() { file.readText().split("\n").let { text -> if (!text.any { it.isBlank() }) text.map { line -> val splits = line.split("/") - AudioOutputBase(splits[0], splits[1].toInt(), splits[2].toFloatOrNull()?:100f) + AudioOutputBase( + splits[0], + splits[1].toInt(), + splits[2].toFloatOrNull() ?: 100f + ) }.toMutableList() else { file.delete() @@ -62,7 +65,7 @@ class SoundMasterActivity : AppCompatActivity() { file.parentFile?.mkdirs() file.createNewFile() } - file.writeText(value.joinToString("\n") { it.pkg + "/" + it.output + "/" + it.volume}) + file.writeText(value.joinToString("\n") { it.pkg + "/" + it.output + "/" + it.volume }) } val volumeBarView by lazy { findViewById(R.id.volumeBars) } @@ -79,18 +82,24 @@ class SoundMasterActivity : AppCompatActivity() { findViewById(R.id.newSlider).setOnClickListener { lastInteractionAt = -1 AppSelectionDialog(this@SoundMasterActivity) { pkg -> - OutputSelectionDialog(this@SoundMasterActivity,SoundMasterService.getAudioDevices()) { device -> + OutputSelectionDialog( + this@SoundMasterActivity, + SoundMasterService.getAudioDevices() + ) { device -> val key = AudioOutputBase(pkg, device?.id ?: -1, 100f) if ( if (SoundMasterService.running) SoundMasterService.isAttachable(key) - else (packageSliders.find { it.pkg == key.pkg && it.output == key.output }==null) + else (packageSliders.find { it.pkg == key.pkg && it.output == key.output } == null) ) { val newPackages = packageSliders newPackages.add(key) packageSliders = newPackages - if (SoundMasterService.running) SoundMasterService.onDynamicAttach(key, device) + if (SoundMasterService.running) SoundMasterService.onDynamicAttach( + key, + device + ) updateSliders() - }else combinationExists() + } else combinationExists() interacted() }.show() }.show() @@ -127,7 +136,7 @@ class SoundMasterActivity : AppCompatActivity() { super.onResume() } - fun updateBtnState() { + private fun updateBtnState() { val btnImage = findViewById(R.id.playPauseButton) btnImage.setImageResource(if (SoundMasterService.running) R.drawable.baseline_stop_24 else R.drawable.baseline_play_arrow_24) btnImage.setOnClickListener { @@ -153,12 +162,24 @@ class SoundMasterActivity : AppCompatActivity() { done: Boolean ) { if (done) { - mediaProjectionManager = - applicationContext.getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager - startActivityForResult( - mediaProjectionManager.createScreenCaptureIntent(), - MEDIA_PROJECTION_REQUEST_CODE - ) + if (output.isBlank()){ + mediaProjectionManager = + applicationContext.getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager + startActivityForResult( + mediaProjectionManager.createScreenCaptureIntent(), + MEDIA_PROJECTION_REQUEST_CODE + ) + } + } + } + + override fun onCommandError(error: String) { + Handler(mainLooper).post { + Toast.makeText( + applicationContext, + getString(R.string.permission_error), + Toast.LENGTH_LONG + ).show() } } }) @@ -169,8 +190,8 @@ class SoundMasterActivity : AppCompatActivity() { Handler(mainLooper).post { Toast.makeText( applicationContext, - "Shizuku Error", - Toast.LENGTH_SHORT + getString(R.string.permission_error), + Toast.LENGTH_LONG ).show() } } @@ -203,16 +224,15 @@ class SoundMasterActivity : AppCompatActivity() { startService(Intent(this, SoundMasterService::class.java).apply { putExtra("packages", packageSliders.map { it.pkg }.toTypedArray()) putExtra("devices", packageSliders.map { it.output }.toIntArray()) - putExtra("volumes",packageSliders.map { it.volume }.toFloatArray()) + putExtra("volumes", packageSliders.map { it.volume }.toFloatArray()) }) - interacted() } else { Toast.makeText( this, "Request to obtain MediaProjection failed.", Toast.LENGTH_SHORT ).show() - interacted() } + interacted() } } @@ -230,7 +250,8 @@ class SoundMasterActivity : AppCompatActivity() { VolumeBarAdapter(this@SoundMasterActivity, packageSliders, { app, vol -> interacted() val newPackages = packageSliders - newPackages[app] = AudioOutputBase(packageSliders[app].pkg, packageSliders[app].output, vol) + newPackages[app] = + AudioOutputBase(packageSliders[app].pkg, packageSliders[app].output, vol) packageSliders = newPackages SoundMasterService.setVolumeOf(packageSliders[app], vol) }, { @@ -253,13 +274,17 @@ class SoundMasterActivity : AppCompatActivity() { SoundMasterService.getAudioDevices() }, { pkg, device -> interacted() - if(SoundMasterService.switchDeviceFor(packageSliders[pkg], device)){ + if (SoundMasterService.switchDeviceFor(packageSliders[pkg], device)) { val newPackages = packageSliders - newPackages[pkg] = AudioOutputBase(packageSliders[pkg].pkg, device?.id?:-1, packageSliders[pkg].volume) + newPackages[pkg] = AudioOutputBase( + packageSliders[pkg].pkg, + device?.id ?: -1, + packageSliders[pkg].volume + ) packageSliders = newPackages updateSliders() true - }else { + } else { combinationExists() false } @@ -271,8 +296,9 @@ class SoundMasterActivity : AppCompatActivity() { }.start() } - private fun combinationExists(){ - Toast.makeText(applicationContext,"Combination already exists.",Toast.LENGTH_SHORT).show() + private fun combinationExists() { + Toast.makeText(applicationContext, "Combination already exists.", Toast.LENGTH_SHORT) + .apply { setGravity(Gravity.TOP, 0, 100) }.show() } companion object { diff --git a/app/src/main/java/com/legendsayantan/adbtools/ThemePatcherActivity.kt b/app/src/main/java/com/legendsayantan/adbtools/ThemePatcherActivity.kt index 49cf523..84050a5 100644 --- a/app/src/main/java/com/legendsayantan/adbtools/ThemePatcherActivity.kt +++ b/app/src/main/java/com/legendsayantan/adbtools/ThemePatcherActivity.kt @@ -12,6 +12,7 @@ import com.legendsayantan.adbtools.lib.Utils.Companion.initialiseStatusBar import com.legendsayantan.adbtools.lib.Utils.Companion.postNotification import java.util.Timer import kotlin.concurrent.schedule + /** * @author legendsayantan */ @@ -37,15 +38,12 @@ class ThemePatcherActivity : AppCompatActivity() { super.onCreate(savedInstanceState) setContentView(R.layout.activity_theme_patcher) initialiseStatusBar() - ShizukuRunner.runAdbCommand("pm grant $packageName android.permission.WRITE_SETTINGS",object : ShizukuRunner.CommandResultListener{ - override fun onCommandResult(output: String, done: Boolean) {} - }) - ShizukuRunner.runAdbCommand("pm grant $packageName android.permission.WRITE_SECURE_SETTINGS",object : ShizukuRunner.CommandResultListener{ - override fun onCommandResult(output: String, done: Boolean) {} - }) - ShizukuRunner.runAdbCommand("pm grant $packageName android.permission.POST_NOTIFICATIONS",object : ShizukuRunner.CommandResultListener{ - override fun onCommandResult(output: String, done: Boolean) {} - }) + ShizukuRunner.runAdbCommand("pm grant $packageName android.permission.WRITE_SETTINGS", + object : ShizukuRunner.CommandResultListener { }) + ShizukuRunner.runAdbCommand("pm grant $packageName android.permission.WRITE_SECURE_SETTINGS", + object : ShizukuRunner.CommandResultListener { }) + ShizukuRunner.runAdbCommand("pm grant $packageName android.permission.POST_NOTIFICATIONS", + object : ShizukuRunner.CommandResultListener { }) var themeStores = packageManager.getAllInstalledApps().filter { it.packageName.contains("theme") } if (themeStores.any { it.loadLabel(packageManager).contains("theme") }) themeStores = @@ -84,10 +82,10 @@ class ThemePatcherActivity : AppCompatActivity() { ) } Timer().schedule(15000) { - patchAll(storepackage){ - if(it.isEmpty()){ + patchAll(storepackage) { + if (it.isEmpty()) { patched() - }else{ + } else { runOnUiThread { postNotification( getString(R.string.themepatcher), @@ -104,37 +102,28 @@ class ThemePatcherActivity : AppCompatActivity() { private fun patchAll(storepackage: String, done: (String) -> Unit) { if (isOnTrial()) { //patch - if(storepackage.isNotEmpty()){ - ShizukuRunner.runAdbCommand("am force-stop $storepackage",object : ShizukuRunner.CommandResultListener{ - override fun onCommandResult(output: String, done: Boolean) {} - }) - } - - zeroByDefault.forEach { - ShizukuRunner.runAdbCommand("settings put system $it 0",object : ShizukuRunner.CommandResultListener{ - override fun onCommandResult(output: String, done: Boolean) {} - }) - ShizukuRunner.runAdbCommand("settings put secure $it 0",object : ShizukuRunner.CommandResultListener{ - override fun onCommandResult(output: String, done: Boolean) {} - }) + if (storepackage.isNotEmpty()) { + ShizukuRunner.runAdbCommand("am force-stop $storepackage", + object : ShizukuRunner.CommandResultListener { }) } - negativeOneByDefault.forEach { - ShizukuRunner.runAdbCommand("settings put system $it -1",object : ShizukuRunner.CommandResultListener{ - override fun onCommandResult(output: String, done: Boolean) {} - }) - ShizukuRunner.runAdbCommand("settings put secure $it -1",object : ShizukuRunner.CommandResultListener{ - override fun onCommandResult(output: String, done: Boolean) {} - }) - } - otherDefaults.forEach { - ShizukuRunner.runAdbCommand("settings put system ${it.key} ${it.value}",object : ShizukuRunner.CommandResultListener{ - override fun onCommandResult(output: String, done: Boolean) {} - }) - ShizukuRunner.runAdbCommand("settings put secure ${it.key} ${it.value}",object : ShizukuRunner.CommandResultListener{ - override fun onCommandResult(output: String, done: Boolean) { - runOnUiThread { done(output) } - } - }) + val tables = listOf("system", "secure") + tables.forEachIndexed { index, table -> + zeroByDefault.forEach { + ShizukuRunner.runAdbCommand("settings put $table $it 0", + object : ShizukuRunner.CommandResultListener { }) + } + negativeOneByDefault.forEach { + ShizukuRunner.runAdbCommand("settings put $table $it -1", + object : ShizukuRunner.CommandResultListener { }) + } + otherDefaults.forEach { + ShizukuRunner.runAdbCommand("settings put $table ${it.key} ${it.value}", + object : ShizukuRunner.CommandResultListener { + override fun onCommandResult(output: String, done: Boolean) { + if (index == tables.size - 1) runOnUiThread { done(output) } + } + }) + } } } } @@ -173,6 +162,4 @@ class ThemePatcherActivity : AppCompatActivity() { } - - } \ No newline at end of file diff --git a/app/src/main/java/com/legendsayantan/adbtools/adapters/DebloatAdapter.kt b/app/src/main/java/com/legendsayantan/adbtools/adapters/DebloatAdapter.kt index 48c74bb..ad99b7b 100644 --- a/app/src/main/java/com/legendsayantan/adbtools/adapters/DebloatAdapter.kt +++ b/app/src/main/java/com/legendsayantan/adbtools/adapters/DebloatAdapter.kt @@ -40,7 +40,7 @@ class DebloatAdapter(private val activity: Activity, private val dataList: HashM val view: View = if (convertView == null) { val inflater = activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater - inflater.inflate(R.layout.debloat_item, null) + inflater.inflate(R.layout.item_debloat, null) } else { convertView } diff --git a/app/src/main/java/com/legendsayantan/adbtools/adapters/VolumeBarAdapter.kt b/app/src/main/java/com/legendsayantan/adbtools/adapters/VolumeBarAdapter.kt index 9e8e695..4b0fd20 100644 --- a/app/src/main/java/com/legendsayantan/adbtools/adapters/VolumeBarAdapter.kt +++ b/app/src/main/java/com/legendsayantan/adbtools/adapters/VolumeBarAdapter.kt @@ -54,7 +54,6 @@ class VolumeBarAdapter( itemView.findViewById(R.id.midReset), itemView.findViewById(R.id.highReset) ) - val detachBtn = itemView.findViewById(R.id.detachBtn) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VolumeBarHolder { @@ -90,6 +89,11 @@ class VolumeBarAdapter( holder.outputExpanded.visibility = View.VISIBLE //spawn radiobuttons holder.outputGroup.removeAllViews() + holder.outputGroup.addView(RadioButton(context).apply { + //detach + text = context.getString(R.string.none) + setOnClickListener { onItemDetached(position) } + }) getDevices().forEach { device -> val rButton = RadioButton(context) showDevice(rButton, device) @@ -113,7 +117,7 @@ class VolumeBarAdapter( holder.expand.animate().rotationX(180f) holder.otherSliders.forEachIndexed { index, slider -> slider.value = onSliderGet(position, index) - slider.addOnChangeListener { s, value, fromUser -> + slider.addOnChangeListener { _, value, _ -> onSliderSet(position, index, value) } } @@ -130,11 +134,6 @@ class VolumeBarAdapter( holder.otherSliders[index].value = if (index == 0) 0f else 50f } } - - //detach - holder.detachBtn.setOnClickListener { onItemDetached(position) } - - } private fun showDevice(v: TextView, d: AudioDeviceInfo?) { diff --git a/app/src/main/java/com/legendsayantan/adbtools/dialog/OutputSelectionDialog.kt b/app/src/main/java/com/legendsayantan/adbtools/dialog/OutputSelectionDialog.kt index 24a19fe..1a48367 100644 --- a/app/src/main/java/com/legendsayantan/adbtools/dialog/OutputSelectionDialog.kt +++ b/app/src/main/java/com/legendsayantan/adbtools/dialog/OutputSelectionDialog.kt @@ -14,7 +14,8 @@ import com.legendsayantan.adbtools.adapters.VolumeBarAdapter */ class OutputSelectionDialog( c: Context, - private val devices: List, val onDeviceSelected: (AudioDeviceInfo?) -> Unit + private val devices: List, + val onDeviceSelected: (AudioDeviceInfo?) -> Unit ) : Dialog(c) { init { setContentView(R.layout.dialog_outputs) diff --git a/app/src/main/java/com/legendsayantan/adbtools/lib/GradleUpdate.kt b/app/src/main/java/com/legendsayantan/adbtools/lib/GradleUpdate.kt index 4ea8ccb..3c023a4 100644 --- a/app/src/main/java/com/legendsayantan/adbtools/lib/GradleUpdate.kt +++ b/app/src/main/java/com/legendsayantan/adbtools/lib/GradleUpdate.kt @@ -18,7 +18,7 @@ import java.net.URL /** * @author legendsayantan */ -class GradleUpdate(val context: Context,val gradleFileUrl: String,val checkInterval:Long) { +class GradleUpdate(val context: Context, private val gradleFileUrl: String, private val checkInterval:Long) { val prefs = context.getSharedPreferences("update",Context.MODE_PRIVATE) private fun check(updateAvailable: (String) -> Unit, noUpdateAvailable: () -> Unit = {}) { if((System.currentTimeMillis() - prefs.getLong("lastchecked",0)) < checkInterval){ diff --git a/app/src/main/java/com/legendsayantan/adbtools/lib/PlayBackThread.kt b/app/src/main/java/com/legendsayantan/adbtools/lib/PlayBackThread.kt index 8a13c42..916f8dd 100644 --- a/app/src/main/java/com/legendsayantan/adbtools/lib/PlayBackThread.kt +++ b/app/src/main/java/com/legendsayantan/adbtools/lib/PlayBackThread.kt @@ -36,10 +36,9 @@ class PlayBackThread( override fun start() { ShizukuRunner.runAdbCommand("appops set $pkg PLAY_AUDIO deny", object : ShizukuRunner.CommandResultListener { - override fun onCommandResult(output: String, done: Boolean) {} override fun onCommandError(error: String) { Handler(context.mainLooper).post { - Toast.makeText(context, "Shizuku Error", Toast.LENGTH_SHORT).show() + Toast.makeText(context, "Error: $error", Toast.LENGTH_SHORT).show() } } }) @@ -156,10 +155,9 @@ class PlayBackThread( playback = false ShizukuRunner.runAdbCommand("appops set $pkg PLAY_AUDIO allow", object : ShizukuRunner.CommandResultListener { - override fun onCommandResult(output: String, done: Boolean) {} override fun onCommandError(error: String) { Handler(context.mainLooper).post { - Toast.makeText(context, "Shizuku Error", Toast.LENGTH_SHORT).show() + Toast.makeText(context, "Error: $error", Toast.LENGTH_SHORT).show() } } }) diff --git a/app/src/main/java/com/legendsayantan/adbtools/lib/ShizukuRunner.kt b/app/src/main/java/com/legendsayantan/adbtools/lib/ShizukuRunner.kt index c0dbff3..ec0cef4 100644 --- a/app/src/main/java/com/legendsayantan/adbtools/lib/ShizukuRunner.kt +++ b/app/src/main/java/com/legendsayantan/adbtools/lib/ShizukuRunner.kt @@ -9,32 +9,47 @@ import java.io.InputStreamReader class ShizukuRunner { interface CommandResultListener { - fun onCommandResult(output: String, done:Boolean) - fun onCommandError(error: String){} + /* + * Runs after the command executes, at least partially. Does not run with 'done' if the command throws an error. + * output: The output of the command + * done: If the command has finished executing + */ + fun onCommandResult(output: String, done: Boolean){} + + /* + * Runs if the command throws an error. + * error: The error message + */ + fun onCommandError(error: String) {} } companion object { - fun runAdbCommand(command: String, listener: CommandResultListener) { + fun runAdbCommand(command: String, listener: CommandResultListener, lineBundle: Int = 50) { Thread { - try{ + try { val process = Shizuku.newProcess(arrayOf("sh", "-c", command), null, "/") val reader = BufferedReader(InputStreamReader(process.inputStream)) + val err = BufferedReader(InputStreamReader(process.errorStream)) val output = StringBuilder() - + val errordata = StringBuilder() var line: String? var linecount = 0 while (reader.readLine().also { line = it } != null) { linecount++ output.append(line).append("\n") - if (linecount == 50) { + if (linecount == lineBundle) { linecount = 0 - listener.onCommandResult(output.toString(),false) + listener.onCommandResult(output.toString(), false) } } - listener.onCommandResult(output.toString(),true) + while (err.readLine().also { line = it } != null) { + errordata.append(line).append("\n") + } + if(errordata.isNotBlank()) listener.onCommandError(errordata.toString()) + else listener.onCommandResult(output.toString(), true) process.waitFor() - }catch (e:Exception){ - listener.onCommandError(e.message?:"No Shizuku") + } catch (e: Exception) { + listener.onCommandError(e.message ?: "No Shizuku") } }.start() diff --git a/app/src/main/java/com/legendsayantan/adbtools/lib/Utils.kt b/app/src/main/java/com/legendsayantan/adbtools/lib/Utils.kt index 1ac54c9..23c3f09 100644 --- a/app/src/main/java/com/legendsayantan/adbtools/lib/Utils.kt +++ b/app/src/main/java/com/legendsayantan/adbtools/lib/Utils.kt @@ -90,8 +90,10 @@ class Utils { "pm list packages", object : ShizukuRunner.CommandResultListener { override fun onCommandResult(output: String, done: Boolean) { - val packages = output.replace("package:", "").split("\n") - callback(packages) + if(done){ + val packages = output.replace("package:", "").split("\n") + callback(packages) + } } }) } diff --git a/app/src/main/java/com/legendsayantan/adbtools/receivers/IntentReceiver.kt b/app/src/main/java/com/legendsayantan/adbtools/receivers/IntentReceiver.kt index b03afee..05f95b5 100644 --- a/app/src/main/java/com/legendsayantan/adbtools/receivers/IntentReceiver.kt +++ b/app/src/main/java/com/legendsayantan/adbtools/receivers/IntentReceiver.kt @@ -4,6 +4,8 @@ import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import com.legendsayantan.adbtools.lib.ShizukuRunner +import com.legendsayantan.adbtools.lib.Utils.Companion.postNotification + /** * @author legendsayantan */ @@ -11,13 +13,13 @@ class IntentReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { val prefs = context.getSharedPreferences("execution", Context.MODE_PRIVATE) - val key = intent.getStringExtra("key") ?: return + val key = intent.getStringExtra("key")?.replace("-","") ?: return if (!prefs.getBoolean("enabled", false) || prefs.getLong( "lockuntil", 0 ) > System.currentTimeMillis() ) return - if (prefs.getString("key", null) != key) { + if (prefs.getString("key", null)?.replace("-","") != key) { prefs.edit().putLong("lockuntil", System.currentTimeMillis() + 300000).apply() return } @@ -32,6 +34,9 @@ class IntentReceiver : BroadcastReceiver() { }) } } + override fun onCommandError(error: String) { + context.postNotification("Command Execution Error", error, false) + } } ShizukuRunner.runAdbCommand(command.toString(), listener) } diff --git a/app/src/main/java/com/legendsayantan/adbtools/services/SoundMasterService.kt b/app/src/main/java/com/legendsayantan/adbtools/services/SoundMasterService.kt index 00e20e6..157a0bc 100644 --- a/app/src/main/java/com/legendsayantan/adbtools/services/SoundMasterService.kt +++ b/app/src/main/java/com/legendsayantan/adbtools/services/SoundMasterService.kt @@ -8,6 +8,7 @@ import android.content.Intent import android.content.pm.PackageManager import android.content.pm.ServiceInfo import android.database.ContentObserver +import android.media.AudioAttributes.ALLOW_CAPTURE_BY_NONE import android.media.AudioDeviceInfo import android.media.AudioManager import android.media.projection.MediaProjection @@ -35,7 +36,6 @@ import kotlin.arrayOf import kotlin.concurrent.timerTask import kotlin.getValue import kotlin.lazy -import kotlin.let class SoundMasterService : Service() { @@ -60,7 +60,11 @@ class SoundMasterService : Service() { } val builder = NotificationCompat.Builder(this, "notifications") - .setContentText("You can change volume to configure ${applicationContext.getString(R.string.soundmaster)} as well.") + .setContentText( + getString( + R.string.soundmaster_initial_noti, + applicationContext.getString(R.string.soundmaster) + )) .setSmallIcon(R.drawable.ic_launcher_foreground) .setPriority(NotificationCompat.PRIORITY_LOW) .setOnlyAlertOnce(true) @@ -90,6 +94,7 @@ class SoundMasterService : Service() { mediaProjectionManager = applicationContext.getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager + audioManager.setAllowedCapturePolicy(ALLOW_CAPTURE_BY_NONE) prepareGetAudioDevices() switchDeviceFor = { key, device -> @@ -184,9 +189,7 @@ class SoundMasterService : Service() { Handler(mainLooper).post { if (SoundMasterActivity.showing) SoundMasterActivity.interacted() else ShizukuRunner.runAdbCommand("am start -n $packageName/${SoundMasterActivity::class.java.canonicalName}", - object : ShizukuRunner.CommandResultListener { - override fun onCommandResult(output: String, done: Boolean) {} - }) + object : ShizukuRunner.CommandResultListener { }) } } } @@ -214,10 +217,10 @@ class SoundMasterService : Service() { var onDynamicDetach: (AudioOutputKey) -> Unit = { _ -> } var getAudioDevices: () -> List = { listOf() } var switchDeviceFor: (AudioOutputKey, AudioDeviceInfo?) -> Boolean = { _, _ -> false } - var setVolumeOf: (AudioOutputKey, Float) -> Unit = { a, b -> } - var getVolumeOf: (AudioOutputKey) -> Float = { p -> 100f } - var setBalanceOf: (AudioOutputKey, Float) -> Unit = { a, b -> } - var getBalanceOf: (AudioOutputKey) -> Float = { _ -> 0f } + var setVolumeOf: (AudioOutputKey, Float) -> Unit = { _, _ -> } + var getVolumeOf: (AudioOutputKey) -> Float = { 100f } + var setBalanceOf: (AudioOutputKey, Float) -> Unit = { _, _ -> } + var getBalanceOf: (AudioOutputKey) -> Float = { 0f } var setBandValueOf: (AudioOutputKey, Int, Float) -> Unit = { _, _, _ -> } var getBandValueOf: (AudioOutputKey, Int) -> Float = { _, _ -> 50f } @@ -232,13 +235,10 @@ class SoundMasterService : Service() { var dev = (getSystemService(Context.AUDIO_SERVICE) as AudioManager).getDevices( AudioManager.GET_DEVICES_OUTPUTS ).filter { - it.type !in arrayOf(7, 18, 25) + it.type !in arrayOf(1, 7, 18, 25) } //block builtin outputs - if (dev.any { it?.type in 3..4 }) dev = dev.filter { it?.type !in 1..2 } - //block earpiece only - if (dev.all { it?.type in 1..2 } || dev.any { it?.type == 8 }) dev = - dev.filter { it?.type != 1 } + if (dev.any { it?.type in 3..4 }) dev = dev.filter { it?.type != 2 } listOf(null) + dev } } diff --git a/app/src/main/res/drawable/baseline_delete_24.xml b/app/src/main/res/drawable/baseline_delete_24.xml deleted file mode 100644 index 883bcaa..0000000 --- a/app/src/main/res/drawable/baseline_delete_24.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/app/src/main/res/font/consolas.ttf b/app/src/main/res/font/consolas.ttf new file mode 100644 index 0000000..a79deb5 Binary files /dev/null and b/app/src/main/res/font/consolas.ttf differ diff --git a/app/src/main/res/layout/activity_sound_master.xml b/app/src/main/res/layout/activity_sound_master.xml index d84e946..f2f27f7 100644 --- a/app/src/main/res/layout/activity_sound_master.xml +++ b/app/src/main/res/layout/activity_sound_master.xml @@ -48,7 +48,6 @@ android:layout_width="wrap_content" android:layout_height="match_parent" android:text="@string/new_slider" - android:translationY="2dp" android:textSize="22sp" android:textColor="@color/white" android:layout_marginHorizontal="7dp" @@ -106,7 +105,6 @@ android:background="@drawable/gradient" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginBottom="25dp" android:animateLayoutChanges="true" android:theme="@style/Base.Theme.AdbTools" android:minHeight="100dp" @@ -121,6 +119,7 @@ diff --git a/app/src/main/res/layout/debloat_item.xml b/app/src/main/res/layout/item_debloat.xml similarity index 100% rename from app/src/main/res/layout/debloat_item.xml rename to app/src/main/res/layout/item_debloat.xml diff --git a/app/src/main/res/layout/item_volumebar.xml b/app/src/main/res/layout/item_volumebar.xml index c593428..996829f 100644 --- a/app/src/main/res/layout/item_volumebar.xml +++ b/app/src/main/res/layout/item_volumebar.xml @@ -133,26 +133,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content"/> - - - - - + - \ No newline at end of file diff --git a/app/src/main/res/layout/simple_item.xml b/app/src/main/res/layout/simple_item.xml deleted file mode 100644 index 0108b37..0000000 --- a/app/src/main/res/layout/simple_item.xml +++ /dev/null @@ -1,7 +0,0 @@ - - diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index cdc707d..fa6254a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -24,7 +24,7 @@ Removable apps - Please wait… Welcome! - Ensure you do not have any adb restrictions, from developer options. + Open the Shizuku app to ensure there are no warnings. Select an apk file to be installed as a downgrade. Start Pick any premium theme / font / wallpaper from the theme store, then take a short Free Trial. @@ -49,8 +49,13 @@ Key copied to clipboard Trial item detected, generating patch.. Selected item was patched as permanent. - Do not un-mute apps that are being controlled by SoundMaster. + Do not un-mute apps that are being controlled by SoundMaster, while SoundMaster is running. Select Audio Output : Confirm to uninstall Links : + You can change volume to configure %1$s as well. Make sure to disable it before you power off the device. + https://cdn.jsdelivr.net/gh/Universal-Debloater-Alliance/universal-android-debloater-next-generation@main/resources/assets/uad_lists.json + None + Permission error! Open the shizuku app to learn more. + Shizuku Error! \ No newline at end of file