package moe.yuuta.workmode.debug import android.graphics.Typeface import android.os.Bundle import android.os.Handler import android.os.Looper import android.text.method.ScrollingMovementMethod import android.util.Log import android.view.ViewGroup import android.widget.Button import android.widget.LinearLayout import android.widget.TextView import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import moe.yuuta.ext.HandlerThreadExecutor import moe.yuuta.workmode.access.DumpResult import moe.yuuta.workmode.suspend.AsyncSuspender import moe.yuuta.workmode.suspend.data.TransferableSuspendedApp import moe.yuuta.workmode.utils.Utils import java.util.concurrent.CompletableFuture class DebugActivity : AppCompatActivity() { companion object { private const val TAG = "Debug" } private var mCurrentFuture: CompletableFuture<*>? = null private lateinit var mLogText: TextView override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) Log.i(TAG, "Starting") val rootView = LinearLayout(this) rootView.orientation = LinearLayout.VERTICAL mLogText = TextView(this) mLogText.typeface = Typeface.MONOSPACE mLogText.movementMethod = ScrollingMovementMethod() rootView.addView(mLogText) registerTestingFunction(rootView, "isSuspended", object : Callback { override fun call(): CompletableFuture<*> { return AsyncSuspender(this@DebugActivity).isSuspended(listOf(TransferableSuspendedApp.of("kh.android.dir"), TransferableSuspendedApp.of("com.android.chrome"))) } }) registerTestingFunction(rootView, "getSuspendedPackageAppExtras", object : Callback { override fun call(): CompletableFuture<*> { return AsyncSuspender(this@DebugActivity).getSuspendedPackageAppExtras(TransferableSuspendedApp.of("com.android.chrome")) } }) registerTestingFunction(rootView, "getSuspendedPackageLauncherExtras", object : Callback { override fun call(): CompletableFuture<*> { return AsyncSuspender(this@DebugActivity).getSuspendedPackageLauncherExtras(TransferableSuspendedApp.of("com.android.chrome")) } }) registerTestingFunction(rootView, "dump", object : Callback { override fun call(): CompletableFuture<*> { return AsyncSuspender(this@DebugActivity).dump(TransferableSuspendedApp.of("com.google.android.dialer", 11)) } }) registerTestingFunction(rootView, "suspend (true)", object : Callback { override fun call(): CompletableFuture<*> { return AsyncSuspender(this@DebugActivity).suspend(listOf(TransferableSuspendedApp.of("kh.android.dir"), TransferableSuspendedApp.of("com.android.chrome")), true) } }) registerTestingFunction(rootView, "suspend (false)", object : Callback { override fun call(): CompletableFuture<*> { return AsyncSuspender(this@DebugActivity).suspend(listOf(TransferableSuspendedApp.of("kh.android.dir"), TransferableSuspendedApp.of("com.android.chrome")), false) } }) registerTestingFunction(rootView, "apply", object : Callback { override fun call(): CompletableFuture<*> { return AsyncSuspender(this@DebugActivity).applyFromSettings() } }) registerTestingFunction(rootView, "getInstalledApplicationsAcrossUser", object : Callback { override fun call(): CompletableFuture<*> { return AsyncSuspender(this@DebugActivity).getInstalledApplicationsAcrossUser(0) } }) Log.d(TAG, "Done, children amount: ${rootView.childCount}") setContentView(rootView) } private fun registerTestingFunction(rootView: ViewGroup, tag: String, onClickListener: Callback) { val btn = Button(this) btn.text = tag btn.setOnClickListener { if (mCurrentFuture != null && !(mCurrentFuture as CompletableFuture<*>).isDone) { Toast.makeText(this, "Current running task is not done yet.", Toast.LENGTH_SHORT).show() return@setOnClickListener } mLogText.text = "" mLogText.append("Started task.\n") mCurrentFuture = onClickListener .call() /* .exceptionally { runOnUiThread { Log.e(TAG, "Exceptionally ${Thread.currentThread().name}", it) mLogText.append("\n") mLogText.append("Exceptionally: $it\n") } return@exceptionally null } */ .handle { result, e -> // handleAsync() doesn't work runOnUiThread { if (result != null && result is DumpResult) { mLogText.append("DumpResult - Launcher Extras: ${Utils.dumpExtras(result.launcherExtras)}\n") } mLogText.append("Done!\n") mLogText.append("Result: $result\n") mLogText.append("Error: $e") } } .thenRunAsync(Runnable { Log.e(TAG, "Then run ${Thread.currentThread().name}") mLogText.append("\n") mLogText.append("Run.") }, HandlerThreadExecutor(Handler(Looper.getMainLooper()))) } rootView.addView(btn) } private interface Callback { fun call(): CompletableFuture<*> } }