Revert "convert more to kotlin"

This reverts commit b20a9fcced.
pull/27/head
androidacy-user 2 years ago
parent e36c36821a
commit 833ecd081d

@ -1,123 +1,115 @@
package com.fox2code.mmm.utils package com.fox2code.mmm.utils;
import android.app.Dialog import android.app.Dialog;
import android.content.ActivityNotFoundException import android.content.ActivityNotFoundException;
import android.content.ComponentName import android.content.ComponentName;
import android.content.Context import android.content.Context;
import android.content.DialogInterface import android.content.Intent;
import android.content.Intent import android.content.pm.PackageManager;
import android.content.pm.PackageManager import android.content.pm.ResolveInfo;
import android.net.Uri import android.net.Uri;
import android.widget.Toast import android.os.Bundle;
import androidx.appcompat.app.AlertDialog import android.widget.Toast;
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
class ExternalHelper private constructor() { import androidx.appcompat.app.AlertDialog;
private var fallback: ComponentName? = null import androidx.core.app.ActivityOptionsCompat;
private var label: CharSequence? = null import androidx.core.util.Supplier;
private var multi = false
fun refreshHelper(context: Context) { import com.fox2code.mmm.Constants;
val intent = Intent( import com.topjohnwu.superuser.internal.UiThreadHandler;
FOX_MMM_OPEN_EXTERNAL,
Uri.parse("https://very-invalid-prefix-for-testing.androidacy.com") import java.util.List;
)
@Suppress("DEPRECATION") val resolveInfos = import timber.log.Timber;
context.packageManager.queryIntentActivities(intent, PackageManager.GET_RESOLVED_FILTER)
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<ResolveInfo> resolveInfos = context.getPackageManager().queryIntentActivities(intent, PackageManager.GET_RESOLVED_FILTER);
if (resolveInfos.isEmpty()) { if (resolveInfos.isEmpty()) {
Timber.i("No external provider installed!") Timber.i("No external provider installed!");
label = if (TEST_MODE) "External" else null label = TEST_MODE ? "External" : null;
multi = TEST_MODE multi = TEST_MODE;
fallback = null fallback = null;
} else { } else {
val resolveInfo = resolveInfos[0] ResolveInfo resolveInfo = resolveInfos.get(0);
Timber.i("Found external provider: %s", resolveInfo.activityInfo.packageName) Timber.i("Found external provider: %s", resolveInfo.activityInfo.packageName);
fallback = fallback = new ComponentName(resolveInfo.activityInfo.packageName, resolveInfo.activityInfo.name);
ComponentName(resolveInfo.activityInfo.packageName, resolveInfo.activityInfo.name) label = resolveInfo.loadLabel(context.getPackageManager());
label = resolveInfo.loadLabel(context.packageManager) multi = resolveInfos.size() >= 2;
multi = resolveInfos.size >= 2
} }
} }
fun openExternal(context: Context, uri: Uri?, repoId: String?): Boolean { public boolean openExternal(Context context, Uri uri, String repoId) {
if (label == null) return false if (label == null)
val param = return false;
ActivityOptionsCompat.makeCustomAnimation(context, com.google.android.material.R.anim.abc_fade_in, com.google.android.material.R.anim.abc_fade_out).toBundle() Bundle param = ActivityOptionsCompat.makeCustomAnimation(context, android.R.anim.fade_in, android.R.anim.fade_out).toBundle();
var intent = Intent(FOX_MMM_OPEN_EXTERNAL, uri) Intent intent = new Intent(FOX_MMM_OPEN_EXTERNAL, uri);
intent.flags = IntentHelper.FLAG_GRANT_URI_PERMISSION intent.setFlags(IntentHelper.FLAG_GRANT_URI_PERMISSION);
intent.putExtra(FOX_MMM_EXTRA_REPO_ID, repoId) intent.putExtra(FOX_MMM_EXTRA_REPO_ID, repoId);
if (multi) { if (multi) {
intent = Intent.createChooser(intent, label) intent = Intent.createChooser(intent, label);
} else { } else {
intent.putExtra(Constants.EXTRA_FADE_OUT, true) intent.putExtra(Constants.EXTRA_FADE_OUT, true);
} }
try { try {
if (multi) { if (multi) {
context.startActivity(intent) context.startActivity(intent);
} else { } else {
context.startActivity(intent, param) context.startActivity(intent, param);
} }
return true return true;
} catch (e: ActivityNotFoundException) { } catch (
Timber.e(e) ActivityNotFoundException e) {
Timber.e(e);
} }
if (fallback != null) { if (fallback != null) {
if (multi) { if (multi) {
intent = Intent(FOX_MMM_OPEN_EXTERNAL, uri) intent = new Intent(FOX_MMM_OPEN_EXTERNAL, uri);
intent.putExtra(FOX_MMM_EXTRA_REPO_ID, repoId) intent.putExtra(FOX_MMM_EXTRA_REPO_ID, repoId);
intent.putExtra(Constants.EXTRA_FADE_OUT, true) intent.putExtra(Constants.EXTRA_FADE_OUT, true);
} }
intent.component = fallback intent.setComponent(fallback);
try { try {
context.startActivity(intent, param) context.startActivity(intent, param);
return true return true;
} catch (e: ActivityNotFoundException) { } catch (
Timber.e(e) ActivityNotFoundException e) {
Timber.e(e);
} }
} }
return false return false;
} }
fun injectButton(builder: AlertDialog.Builder, uriSupplier: Supplier<Uri?>, repoId: String?) { public void injectButton(AlertDialog.Builder builder, Supplier<Uri> uriSupplier, String repoId) {
if (label == null) return if (label == null)
builder.setNeutralButton(label) { dialog: DialogInterface, _: Int -> return;
val context = (dialog as Dialog).context builder.setNeutralButton(label, (dialog, button) -> {
object : Thread("Async downloader") { Context context = ((Dialog) dialog).getContext();
override fun run() { new Thread("Async downloader") {
val uri = uriSupplier.get() @Override
if (uri == null) { public void run() {
UiThreadHandler.run { final Uri uri = uriSupplier.get();
Toast.makeText( if (uri == null)
context, return;
"Failed to get uri", UiThreadHandler.run(() -> {
Toast.LENGTH_SHORT
).show()
}
return
}
UiThreadHandler.run {
if (!openExternal(context, uri, repoId)) { if (!openExternal(context, uri, repoId)) {
Toast.makeText( Toast.makeText(context, "Failed to launch external activity", Toast.LENGTH_SHORT).show();
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"
} }
} }

@ -1,13 +1,15 @@
package com.fox2code.mmm.utils package com.fox2code.mmm.utils;
class FastException private constructor() : RuntimeException() { import androidx.annotation.NonNull;
@Synchronized
override fun fillInStackTrace(): Throwable { public final class FastException extends RuntimeException {
return this public static final FastException INSTANCE = new FastException();
}
private FastException() {}
companion object { @NonNull
@JvmField @Override
val INSTANCE = FastException() public synchronized Throwable fillInStackTrace() {
return this;
} }
} }

@ -1,29 +1,25 @@
package com.fox2code.mmm.utils package com.fox2code.mmm.utils;
import android.app.AlarmManager import android.app.AlarmManager;
import android.app.PendingIntent import android.app.PendingIntent;
import android.content.Context import android.content.Context;
import android.content.Intent import android.content.Intent;
import com.fox2code.mmm.MainActivity
import java.util.concurrent.ThreadLocalRandom
import kotlin.system.exitProcess
enum class ProcessHelper { import com.fox2code.mmm.MainActivity;
import java.util.concurrent.ThreadLocalRandom;
public enum ProcessHelper {
; ;
private static final int sPendingIntentId = ThreadLocalRandom.current().nextInt(100, 1000000 + 1);
companion object { public static void restartApplicationProcess(Context context) {
private val sPendingIntentId = ThreadLocalRandom.current().nextInt(100, 1000000 + 1) Intent mStartActivity = new Intent(context, MainActivity.class);
@JvmStatic mStartActivity.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
fun restartApplicationProcess(context: Context) { PendingIntent mPendingIntent = PendingIntent.getActivity(context, sPendingIntentId,
val mStartActivity = Intent(context, MainActivity::class.java) mStartActivity, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE);
mStartActivity.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK AlarmManager mgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
val mPendingIntent = PendingIntent.getActivity( mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent);
context, sPendingIntentId, System.exit(0); // Exit app process
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
}
} }
} }

@ -1,76 +1,79 @@
package com.fox2code.mmm.utils package com.fox2code.mmm.utils;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
/** /**
* Manager that want both to be thread safe and not to worry about thread safety * Manager that want both to be thread safe and not to worry about thread safety
* [.scan] and [.update] can be called from multiple * {@link #scan()} and {@link #update(UpdateListener)} can be called from multiple
* thread at the same time, [.scanInternal] will only be * thread at the same time, {@link #scanInternal(UpdateListener)} will only be
* called from one thread at a time only. * called from one thread at a time only.
*/ */
abstract class SyncManager { public abstract class SyncManager {
@JvmField private static final UpdateListener NO_OP = value -> {};
protected val syncLock = Any() protected final Object syncLock = new Object();
private var syncing = false private boolean syncing;
private var lastSync: Long = 0 private long lastSync;
fun scanAsync() {
if (!syncing) { public final void scanAsync() {
Thread({ this.scan() }, "Scan Thread").start() if (!this.syncing) {
new Thread(this::scan, "Scan Thread").start();
} }
} }
fun scan() { public final void scan() {
update(null) this.update(null);
} }
// MultiThread friendly method // MultiThread friendly method
fun update(updateListener: UpdateListener?) { public final void update(@Nullable UpdateListener updateListener) {
@Suppress("NAME_SHADOWING") var updateListener = updateListener if (updateListener == null) updateListener = NO_OP;
if (updateListener == null) updateListener = NO_OP if (!this.syncing) {
if (!syncing) {
// Do scan // Do scan
synchronized(syncLock) { synchronized (this.syncLock) {
if (System.currentTimeMillis() < lastSync + 50L) return // Skip sync if it was synced too recently if (System.currentTimeMillis() < this.lastSync + 50L)
syncing = true return; // Skip sync if it was synced too recently
this.syncing = true;
try { try {
scanInternal(updateListener) this.scanInternal(updateListener);
} finally { } finally {
lastSync = System.currentTimeMillis() this.lastSync = System.currentTimeMillis();
syncing = false this.syncing = false;
} }
} }
} else { } else {
// Wait for current scan // Wait for current scan
synchronized(syncLock) { Thread.yield() } synchronized (this.syncLock) {
Thread.yield();
}
} }
} }
// Pause execution until the scan is completed if one is currently running // Pause execution until the scan is completed if one is currently running
fun afterScan() { public final void afterScan() {
if (syncing) synchronized(syncLock) { Thread.yield() } if (this.syncing) synchronized (this.syncLock) { Thread.yield(); }
} }
fun runAfterScan(runnable: Runnable) { public final void runAfterScan(Runnable runnable) {
synchronized(syncLock) { runnable.run() } synchronized (this.syncLock) {
runnable.run();
}
} }
fun afterUpdate() { public final void afterUpdate() {
if (syncing) synchronized(syncLock) { Thread.yield() } if (this.syncing) synchronized (this.syncLock) { Thread.yield(); }
} }
fun runAfterUpdate(runnable: Runnable) { public final void runAfterUpdate(Runnable runnable) {
synchronized(syncLock) { runnable.run() } synchronized (this.syncLock) {
runnable.run();
}
} }
// This method can't be called twice at the same time. // This method can't be called twice at the same time.
protected abstract fun scanInternal(updateListener: UpdateListener) protected abstract void scanInternal(@NonNull 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);
} }
} }

Loading…
Cancel
Save