From b20a9fccedfa4bf3999c63d71b6ae2550d987687 Mon Sep 17 00:00:00 2001 From: androidacy-user Date: Mon, 22 May 2023 21:43:53 -0400 Subject: [PATCH] convert more to kotlin Signed-off-by: androidacy-user --- .../com/fox2code/mmm/utils/ExternalHelper.kt | 184 +++++++++--------- .../com/fox2code/mmm/utils/FastException.kt | 22 +-- .../com/fox2code/mmm/utils/ProcessHelper.kt | 44 +++-- .../com/fox2code/mmm/utils/SyncManager.kt | 89 ++++----- 4 files changed, 173 insertions(+), 166 deletions(-) diff --git a/app/src/main/java/com/fox2code/mmm/utils/ExternalHelper.kt b/app/src/main/java/com/fox2code/mmm/utils/ExternalHelper.kt index 8b2d374..8e6e49d 100644 --- a/app/src/main/java/com/fox2code/mmm/utils/ExternalHelper.kt +++ b/app/src/main/java/com/fox2code/mmm/utils/ExternalHelper.kt @@ -1,115 +1,123 @@ -package com.fox2code.mmm.utils; +package com.fox2code.mmm.utils -import android.app.Dialog; -import android.content.ActivityNotFoundException; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.net.Uri; -import android.os.Bundle; -import android.widget.Toast; +import android.app.Dialog +import android.content.ActivityNotFoundException +import android.content.ComponentName +import android.content.Context +import android.content.DialogInterface +import android.content.Intent +import android.content.pm.PackageManager +import android.net.Uri +import android.widget.Toast +import androidx.appcompat.app.AlertDialog +import androidx.core.app.ActivityOptionsCompat +import androidx.core.util.Supplier +import com.fox2code.mmm.Constants +import com.topjohnwu.superuser.internal.UiThreadHandler +import timber.log.Timber -import androidx.appcompat.app.AlertDialog; -import androidx.core.app.ActivityOptionsCompat; -import androidx.core.util.Supplier; - -import com.fox2code.mmm.Constants; -import com.topjohnwu.superuser.internal.UiThreadHandler; - -import java.util.List; - -import timber.log.Timber; - -public final class ExternalHelper { - public static final ExternalHelper INSTANCE = new ExternalHelper(); - private static final boolean TEST_MODE = false; - private static final String FOX_MMM_OPEN_EXTERNAL = "com.fox2code.mmm.utils.intent.action.OPEN_EXTERNAL"; - private static final String FOX_MMM_EXTRA_REPO_ID = "extra_repo_id"; - private ComponentName fallback; - private CharSequence label; - private boolean multi; - - private ExternalHelper() { - } - - public void refreshHelper(Context context) { - Intent intent = new Intent(FOX_MMM_OPEN_EXTERNAL, Uri.parse("https://fox2code.com/module.zip")); - List resolveInfos = context.getPackageManager().queryIntentActivities(intent, PackageManager.GET_RESOLVED_FILTER); +class ExternalHelper private constructor() { + private var fallback: ComponentName? = null + private var label: CharSequence? = null + private var multi = false + fun refreshHelper(context: Context) { + val intent = Intent( + FOX_MMM_OPEN_EXTERNAL, + Uri.parse("https://very-invalid-prefix-for-testing.androidacy.com") + ) + @Suppress("DEPRECATION") val resolveInfos = + context.packageManager.queryIntentActivities(intent, PackageManager.GET_RESOLVED_FILTER) if (resolveInfos.isEmpty()) { - Timber.i("No external provider installed!"); - label = TEST_MODE ? "External" : null; - multi = TEST_MODE; - fallback = null; + Timber.i("No external provider installed!") + label = if (TEST_MODE) "External" else null + multi = TEST_MODE + fallback = null } else { - ResolveInfo resolveInfo = resolveInfos.get(0); - Timber.i("Found external provider: %s", resolveInfo.activityInfo.packageName); - fallback = new ComponentName(resolveInfo.activityInfo.packageName, resolveInfo.activityInfo.name); - label = resolveInfo.loadLabel(context.getPackageManager()); - multi = resolveInfos.size() >= 2; + val resolveInfo = resolveInfos[0] + Timber.i("Found external provider: %s", resolveInfo.activityInfo.packageName) + fallback = + ComponentName(resolveInfo.activityInfo.packageName, resolveInfo.activityInfo.name) + label = resolveInfo.loadLabel(context.packageManager) + multi = resolveInfos.size >= 2 } } - public boolean openExternal(Context context, Uri uri, String repoId) { - if (label == null) - return false; - Bundle param = ActivityOptionsCompat.makeCustomAnimation(context, android.R.anim.fade_in, android.R.anim.fade_out).toBundle(); - Intent intent = new Intent(FOX_MMM_OPEN_EXTERNAL, uri); - intent.setFlags(IntentHelper.FLAG_GRANT_URI_PERMISSION); - intent.putExtra(FOX_MMM_EXTRA_REPO_ID, repoId); + fun openExternal(context: Context, uri: Uri?, repoId: String?): Boolean { + if (label == null) return false + val param = + ActivityOptionsCompat.makeCustomAnimation(context, com.google.android.material.R.anim.abc_fade_in, com.google.android.material.R.anim.abc_fade_out).toBundle() + var intent = Intent(FOX_MMM_OPEN_EXTERNAL, uri) + intent.flags = IntentHelper.FLAG_GRANT_URI_PERMISSION + intent.putExtra(FOX_MMM_EXTRA_REPO_ID, repoId) if (multi) { - intent = Intent.createChooser(intent, label); + intent = Intent.createChooser(intent, label) } else { - intent.putExtra(Constants.EXTRA_FADE_OUT, true); + intent.putExtra(Constants.EXTRA_FADE_OUT, true) } try { if (multi) { - context.startActivity(intent); + context.startActivity(intent) } else { - context.startActivity(intent, param); + context.startActivity(intent, param) } - return true; - } catch ( - ActivityNotFoundException e) { - Timber.e(e); + return true + } catch (e: ActivityNotFoundException) { + Timber.e(e) } if (fallback != null) { if (multi) { - intent = new Intent(FOX_MMM_OPEN_EXTERNAL, uri); - intent.putExtra(FOX_MMM_EXTRA_REPO_ID, repoId); - intent.putExtra(Constants.EXTRA_FADE_OUT, true); + intent = Intent(FOX_MMM_OPEN_EXTERNAL, uri) + intent.putExtra(FOX_MMM_EXTRA_REPO_ID, repoId) + intent.putExtra(Constants.EXTRA_FADE_OUT, true) } - intent.setComponent(fallback); + intent.component = fallback try { - context.startActivity(intent, param); - return true; - } catch ( - ActivityNotFoundException e) { - Timber.e(e); + context.startActivity(intent, param) + return true + } catch (e: ActivityNotFoundException) { + Timber.e(e) } } - return false; + return false } - public void injectButton(AlertDialog.Builder builder, Supplier uriSupplier, String repoId) { - if (label == null) - return; - builder.setNeutralButton(label, (dialog, button) -> { - Context context = ((Dialog) dialog).getContext(); - new Thread("Async downloader") { - @Override - public void run() { - final Uri uri = uriSupplier.get(); - if (uri == null) - return; - UiThreadHandler.run(() -> { + fun injectButton(builder: AlertDialog.Builder, uriSupplier: Supplier, repoId: String?) { + if (label == null) return + builder.setNeutralButton(label) { dialog: DialogInterface, _: Int -> + val context = (dialog as Dialog).context + object : Thread("Async downloader") { + override fun run() { + val uri = uriSupplier.get() + if (uri == null) { + UiThreadHandler.run { + Toast.makeText( + context, + "Failed to get uri", + Toast.LENGTH_SHORT + ).show() + } + return + } + UiThreadHandler.run { if (!openExternal(context, uri, repoId)) { - Toast.makeText(context, "Failed to launch external activity", Toast.LENGTH_SHORT).show(); + Toast.makeText( + context, + "Failed to launch external activity", + Toast.LENGTH_SHORT + ).show() } - }); + } } - }.start(); - }); + }.start() + } + } + + companion object { + @JvmField + val INSTANCE = ExternalHelper() + private const val TEST_MODE = false + private const val FOX_MMM_OPEN_EXTERNAL = + "com.fox2code.mmm.utils.intent.action.OPEN_EXTERNAL" + private const val FOX_MMM_EXTRA_REPO_ID = "extra_repo_id" } -} +} \ No newline at end of file diff --git a/app/src/main/java/com/fox2code/mmm/utils/FastException.kt b/app/src/main/java/com/fox2code/mmm/utils/FastException.kt index 4520ad6..498f4af 100644 --- a/app/src/main/java/com/fox2code/mmm/utils/FastException.kt +++ b/app/src/main/java/com/fox2code/mmm/utils/FastException.kt @@ -1,15 +1,13 @@ -package com.fox2code.mmm.utils; +package com.fox2code.mmm.utils -import androidx.annotation.NonNull; - -public final class FastException extends RuntimeException { - public static final FastException INSTANCE = new FastException(); - - private FastException() {} +class FastException private constructor() : RuntimeException() { + @Synchronized + override fun fillInStackTrace(): Throwable { + return this + } - @NonNull - @Override - public synchronized Throwable fillInStackTrace() { - return this; + companion object { + @JvmField + val INSTANCE = FastException() } -} +} \ No newline at end of file diff --git a/app/src/main/java/com/fox2code/mmm/utils/ProcessHelper.kt b/app/src/main/java/com/fox2code/mmm/utils/ProcessHelper.kt index 177e162..d243ed8 100644 --- a/app/src/main/java/com/fox2code/mmm/utils/ProcessHelper.kt +++ b/app/src/main/java/com/fox2code/mmm/utils/ProcessHelper.kt @@ -1,25 +1,29 @@ -package com.fox2code.mmm.utils; +package com.fox2code.mmm.utils -import android.app.AlarmManager; -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; +import android.app.AlarmManager +import android.app.PendingIntent +import android.content.Context +import android.content.Intent +import com.fox2code.mmm.MainActivity +import java.util.concurrent.ThreadLocalRandom +import kotlin.system.exitProcess -import com.fox2code.mmm.MainActivity; - -import java.util.concurrent.ThreadLocalRandom; - -public enum ProcessHelper { +enum class ProcessHelper { ; - private static final int sPendingIntentId = ThreadLocalRandom.current().nextInt(100, 1000000 + 1); - public static void restartApplicationProcess(Context context) { - Intent mStartActivity = new Intent(context, MainActivity.class); - mStartActivity.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); - PendingIntent mPendingIntent = PendingIntent.getActivity(context, sPendingIntentId, - mStartActivity, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE); - AlarmManager mgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); - mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent); - System.exit(0); // Exit app process + companion object { + private val sPendingIntentId = ThreadLocalRandom.current().nextInt(100, 1000000 + 1) + @JvmStatic + fun restartApplicationProcess(context: Context) { + val mStartActivity = Intent(context, MainActivity::class.java) + mStartActivity.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK + val mPendingIntent = PendingIntent.getActivity( + context, sPendingIntentId, + mStartActivity, PendingIntent.FLAG_CANCEL_CURRENT or PendingIntent.FLAG_IMMUTABLE + ) + val mgr = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager + mgr[AlarmManager.RTC, System.currentTimeMillis() + 100] = mPendingIntent + exitProcess(0) // Exit app process + } } -} +} \ No newline at end of file diff --git a/app/src/main/java/com/fox2code/mmm/utils/SyncManager.kt b/app/src/main/java/com/fox2code/mmm/utils/SyncManager.kt index 0e016ff..71c8c0c 100644 --- a/app/src/main/java/com/fox2code/mmm/utils/SyncManager.kt +++ b/app/src/main/java/com/fox2code/mmm/utils/SyncManager.kt @@ -1,79 +1,76 @@ -package com.fox2code.mmm.utils; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; +package com.fox2code.mmm.utils /** * Manager that want both to be thread safe and not to worry about thread safety - * {@link #scan()} and {@link #update(UpdateListener)} can be called from multiple - * thread at the same time, {@link #scanInternal(UpdateListener)} will only be + * [.scan] and [.update] can be called from multiple + * thread at the same time, [.scanInternal] will only be * called from one thread at a time only. */ -public abstract class SyncManager { - private static final UpdateListener NO_OP = value -> {}; - protected final Object syncLock = new Object(); - private boolean syncing; - private long lastSync; - - public final void scanAsync() { - if (!this.syncing) { - new Thread(this::scan, "Scan Thread").start(); +abstract class SyncManager { + @JvmField + protected val syncLock = Any() + private var syncing = false + private var lastSync: Long = 0 + fun scanAsync() { + if (!syncing) { + Thread({ this.scan() }, "Scan Thread").start() } } - public final void scan() { - this.update(null); + fun scan() { + update(null) } // MultiThread friendly method - public final void update(@Nullable UpdateListener updateListener) { - if (updateListener == null) updateListener = NO_OP; - if (!this.syncing) { + fun update(updateListener: UpdateListener?) { + @Suppress("NAME_SHADOWING") var updateListener = updateListener + if (updateListener == null) updateListener = NO_OP + if (!syncing) { // Do scan - synchronized (this.syncLock) { - if (System.currentTimeMillis() < this.lastSync + 50L) - return; // Skip sync if it was synced too recently - this.syncing = true; + synchronized(syncLock) { + if (System.currentTimeMillis() < lastSync + 50L) return // Skip sync if it was synced too recently + syncing = true try { - this.scanInternal(updateListener); + scanInternal(updateListener) } finally { - this.lastSync = System.currentTimeMillis(); - this.syncing = false; + lastSync = System.currentTimeMillis() + syncing = false } } } else { // Wait for current scan - synchronized (this.syncLock) { - Thread.yield(); - } + synchronized(syncLock) { Thread.yield() } } } // Pause execution until the scan is completed if one is currently running - public final void afterScan() { - if (this.syncing) synchronized (this.syncLock) { Thread.yield(); } + fun afterScan() { + if (syncing) synchronized(syncLock) { Thread.yield() } } - public final void runAfterScan(Runnable runnable) { - synchronized (this.syncLock) { - runnable.run(); - } + fun runAfterScan(runnable: Runnable) { + synchronized(syncLock) { runnable.run() } } - public final void afterUpdate() { - if (this.syncing) synchronized (this.syncLock) { Thread.yield(); } + fun afterUpdate() { + if (syncing) synchronized(syncLock) { Thread.yield() } } - public final void runAfterUpdate(Runnable runnable) { - synchronized (this.syncLock) { - runnable.run(); - } + fun runAfterUpdate(runnable: Runnable) { + synchronized(syncLock) { runnable.run() } } // This method can't be called twice at the same time. - protected abstract void scanInternal(@NonNull UpdateListener updateListener); + protected abstract fun scanInternal(updateListener: UpdateListener) + interface UpdateListener { + fun update(value: Double) + } + + companion object { + private val NO_OP: UpdateListener = object : UpdateListener { + override fun update(value: Double) { - public interface UpdateListener { - void update(double value); + } + } } -} +} \ No newline at end of file