Refactor dependency with lazykt

This commit is contained in:
tarsin committed 2022-12-04 22:31:02 +08:00
1 parent d4482dec23
commit 68d1e39410
36 files changed
+490 -839

No files matched your search

@@ -14,543 +14,315 @@
* limitations under the License.
*/
package com.hippo.ehviewer;
package com.hippo.ehviewer
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.ComponentCallbacks2;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Debug;
import android.text.Html;
import android.text.method.LinkMovementMethod;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.annotation.SuppressLint
import android.app.Activity
import android.content.ComponentCallbacks2
import android.os.Build
import android.text.Html
import android.text.method.LinkMovementMethod
import android.view.View
import android.widget.TextView
import androidx.appcompat.app.AppCompatDelegate
import androidx.collection.LruCache
import androidx.core.os.LocaleListCompat
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.ProcessLifecycleOwner
import coil.Coil
import coil.ImageLoader
import com.hippo.Native
import com.hippo.app.BaseDialogBuilder
import com.hippo.beerbelly.SimpleDiskCache
import com.hippo.ehviewer.client.EhClient
import com.hippo.ehviewer.client.EhCookieStore
import com.hippo.ehviewer.client.EhDns
import com.hippo.ehviewer.client.EhEngine
import com.hippo.ehviewer.client.EhRequestBuilder
import com.hippo.ehviewer.client.EhSSLSocketFactory
import com.hippo.ehviewer.client.EhUrl
import com.hippo.ehviewer.client.EhX509TrustManager
import com.hippo.ehviewer.client.data.GalleryDetail
import com.hippo.ehviewer.client.parser.EventPaneParser
import com.hippo.ehviewer.download.DownloadManager
import com.hippo.ehviewer.spider.SpiderDen
import com.hippo.ehviewer.ui.CommonOperations
import com.hippo.ehviewer.ui.EhActivity
import com.hippo.image.Image
import com.hippo.network.StatusCodeException
import com.hippo.scene.SceneApplication
import com.hippo.util.BitmapUtils
import com.hippo.util.ExceptionUtils
import com.hippo.util.IoThreadPoolExecutor
import com.hippo.util.ReadableTime
import com.hippo.yorozuya.FileUtils
import com.hippo.yorozuya.IntIdGenerator
import okhttp3.Cache
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.OkHttpClient
import java.io.File
import java.security.KeyStore
import java.util.Arrays
import javax.net.ssl.TrustManagerFactory
import javax.net.ssl.X509TrustManager
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.collection.LruCache;
import androidx.core.os.LocaleListCompat;
import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.ProcessLifecycleOwner;
import com.hippo.Native;
import com.hippo.app.BaseDialogBuilder;
import com.hippo.beerbelly.SimpleDiskCache;
import com.hippo.ehviewer.client.EhClient;
import com.hippo.ehviewer.client.EhCookieStore;
import com.hippo.ehviewer.client.EhDns;
import com.hippo.ehviewer.client.EhEngine;
import com.hippo.ehviewer.client.EhRequestBuilder;
import com.hippo.ehviewer.client.EhSSLSocketFactory;
import com.hippo.ehviewer.client.EhUrl;
import com.hippo.ehviewer.client.EhX509TrustManager;
import com.hippo.ehviewer.client.data.GalleryDetail;
import com.hippo.ehviewer.client.parser.EventPaneParser;
import com.hippo.ehviewer.download.DownloadManager;
import com.hippo.ehviewer.spider.SpiderDen;
import com.hippo.ehviewer.ui.CommonOperations;
import com.hippo.ehviewer.ui.EhActivity;
import com.hippo.image.Image;
import com.hippo.network.StatusCodeException;
import com.hippo.scene.SceneApplication;
import com.hippo.unifile.UniFile;
import com.hippo.util.BitmapUtils;
import com.hippo.util.ExceptionUtils;
import com.hippo.util.IoThreadPoolExecutor;
import com.hippo.util.ReadableTime;
import com.hippo.yorozuya.FileUtils;
import com.hippo.yorozuya.IntIdGenerator;
import com.hippo.yorozuya.OSUtils;
import com.hippo.yorozuya.SimpleHandler;
import java.io.File;
import java.security.KeyStore;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import coil.Coil;
import coil.ImageLoader;
import okhttp3.Cache;
import okhttp3.Call;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
public class EhApplication extends SceneApplication {
public static final boolean BETA = false;
private static final String TAG = EhApplication.class.getSimpleName();
private static final String KEY_GLOBAL_STUFF_NEXT_ID = "global_stuff_next_id";
private static final boolean DEBUG_CONACO = false;
private static final boolean DEBUG_PRINT_NATIVE_MEMORY = false;
private static final boolean DEBUG_PRINT_IMAGE_COUNT = false;
private static final long DEBUG_PRINT_INTERVAL = 3000L;
public static boolean locked = true;
public static long locked_last_leave_time = 0;
private static EhApplication instance;
private final IntIdGenerator mIdGenerator = new IntIdGenerator();
private final HashMap<Integer, Object> mGlobalStuffMap = new HashMap<>();
private final List<Activity> mActivityList = new ArrayList<>();
private EhCookieStore mEhCookieStore;
private EhClient mEhClient;
private EhProxySelector mEhProxySelector;
private OkHttpClient mOkHttpClient;
private Cache mOkHttpCache;
private LruCache<Long, GalleryDetail> mGalleryDetailCache;
private SimpleDiskCache mSpiderInfoCache;
private DownloadManager mDownloadManager;
private Hosts mHosts;
private FavouriteStatusRouter mFavouriteStatusRouter;
private boolean initialized = false;
public static EhApplication getInstance() {
return instance;
}
public static EhCookieStore getEhCookieStore(@NonNull Context context) {
EhApplication application = ((EhApplication) context.getApplicationContext());
if (application.mEhCookieStore == null) {
application.mEhCookieStore = new EhCookieStore(context);
class EhApplication : SceneApplication() {
private val mIdGenerator = IntIdGenerator()
private val mGlobalStuffMap = HashMap<Int, Any>()
private val mActivityList = ArrayList<Activity>()
private var initialized = false
val topActivity: EhActivity?
get() = if (mActivityList.isNotEmpty()) {
mActivityList[mActivityList.size - 1] as EhActivity
} else {
null
}
return application.mEhCookieStore;
}
@NonNull
public static EhClient getEhClient(@NonNull Context context) {
EhApplication application = ((EhApplication) context.getApplicationContext());
if (application.mEhClient == null) {
application.mEhClient = new EhClient(application);
}
return application.mEhClient;
}
@NonNull
public static EhProxySelector getEhProxySelector(@NonNull Context context) {
EhApplication application = ((EhApplication) context.getApplicationContext());
if (application.mEhProxySelector == null) {
application.mEhProxySelector = new EhProxySelector();
}
return application.mEhProxySelector;
}
@NonNull
public static OkHttpClient getOkHttpClient(@NonNull Context context) {
EhApplication application = ((EhApplication) context.getApplicationContext());
if (application.mOkHttpClient == null) {
OkHttpClient.Builder builder = new OkHttpClient.Builder()
.cookieJar(getEhCookieStore(application))
.cache(getOkHttpCache(application))
.dns(new EhDns(application))
.proxySelector(getEhProxySelector(application));
if (Settings.getDF()) {
X509TrustManager trustManager;
try {
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init((KeyStore) null);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager trustManager1)) {
throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustManagers));
}
trustManager = trustManager1;
} catch (Exception e) {
e.printStackTrace();
trustManager = new EhX509TrustManager();
}
builder.sslSocketFactory(new EhSSLSocketFactory(), trustManager);
}
application.mOkHttpClient = builder.build();
}
return application.mOkHttpClient;
}
@NonNull
public static Cache getOkHttpCache(@NonNull Context context) {
EhApplication application = ((EhApplication) context.getApplicationContext());
if (application.mOkHttpCache == null) {
application.mOkHttpCache = new Cache(new File(application.getCacheDir(), "http_cache"), 50L * 1024L * 1024L);
}
return application.mOkHttpCache;
}
private static int getMemoryCacheMaxSize() {
return Math.min(20 * 1024 * 1024, (int) OSUtils.getAppMaxMemory());
}
@NonNull
public static LruCache<Long, GalleryDetail> getGalleryDetailCache(@NonNull Context context) {
EhApplication application = ((EhApplication) context.getApplicationContext());
if (application.mGalleryDetailCache == null) {
// Max size 25, 3 min timeout
application.mGalleryDetailCache = new LruCache<>(25);
getFavouriteStatusRouter().addListener((gid, slot) -> {
GalleryDetail gd = application.mGalleryDetailCache.get(gid);
if (gd != null) {
gd.favoriteSlot = slot;
}
});
}
return application.mGalleryDetailCache;
}
@NonNull
public static SimpleDiskCache getSpiderInfoCache(@NonNull Context context) {
EhApplication application = ((EhApplication) context.getApplicationContext());
if (null == application.mSpiderInfoCache) {
application.mSpiderInfoCache = new SimpleDiskCache(
new File(context.getCacheDir(), "spider_info"), 20 * 1024 * 1024); // 20M
}
return application.mSpiderInfoCache;
}
@NonNull
public static DownloadManager getDownloadManager() {
return getDownloadManager(instance);
}
@NonNull
public static DownloadManager getDownloadManager(@NonNull Context context) {
EhApplication application = ((EhApplication) context.getApplicationContext());
if (application.mDownloadManager == null) {
application.mDownloadManager = new DownloadManager(application);
}
return application.mDownloadManager;
}
@NonNull
public static Hosts getHosts(@NonNull Context context) {
EhApplication application = ((EhApplication) context.getApplicationContext());
if (application.mHosts == null) {
application.mHosts = new Hosts(application, "hosts.db");
}
return application.mHosts;
}
@NonNull
public static FavouriteStatusRouter getFavouriteStatusRouter() {
return getFavouriteStatusRouter(getInstance());
}
@NonNull
public static FavouriteStatusRouter getFavouriteStatusRouter(@NonNull Context context) {
EhApplication application = ((EhApplication) context.getApplicationContext());
if (application.mFavouriteStatusRouter == null) {
application.mFavouriteStatusRouter = new FavouriteStatusRouter();
}
return application.mFavouriteStatusRouter;
}
@SuppressLint("StaticFieldLeak")
@Override
public void onCreate() {
ProcessLifecycleOwner.get().getLifecycle().addObserver(new EhlifecycleObserver());
instance = this;
Thread.UncaughtExceptionHandler handler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler((t, e) -> {
override fun onCreate() {
ProcessLifecycleOwner.get().lifecycle.addObserver(EhlifecycleObserver())
application = this
val handler = Thread.getDefaultUncaughtExceptionHandler()
Thread.setDefaultUncaughtExceptionHandler { t, e ->
try {
// Always save crash file if onCreate() is not done
if (!initialized || Settings.getSaveCrashLog()) {
Crash.saveCrashLog(instance, e);
Crash.saveCrashLog(application, e)
}
} catch (Throwable ignored) {
} catch (ignored: Throwable) {
}
if (handler != null) {
handler.uncaughtException(t, e);
}
});
super.onCreate();
Image.initialize(this);
Native.initialize();
GetText.initialize(this);
StatusCodeException.initialize(this);
Settings.initialize(this);
ReadableTime.initialize(this);
AppConfig.initialize(this);
SpiderDen.initialize(this);
EhDB.initialize(this);
EhEngine.initialize();
BitmapUtils.initialize(this);
Coil.setImageLoader(new ImageLoader.Builder(this).okHttpClient(getOkHttpClient(this)).build());
handler?.uncaughtException(t, e)
}
super.onCreate()
Image.initialize(this)
Native.initialize()
GetText.initialize(this)
StatusCodeException.initialize(this)
Settings.initialize(this)
ReadableTime.initialize(this)
AppConfig.initialize(this)
SpiderDen.initialize(this)
EhDB.initialize(this)
EhEngine.initialize()
BitmapUtils.initialize(this)
Coil.setImageLoader(ImageLoader.Builder(this).okHttpClient(okHttpClient).build())
// Locales can be managed by system automatically above Snow Cone v2
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU)
AppCompatDelegate.setApplicationLocales(LocaleListCompat.create(Settings.getLocale()));
AppCompatDelegate.setApplicationLocales(LocaleListCompat.create(Settings.getLocale()))
AppCompatDelegate.setDefaultNightMode(Settings.getTheme())
AppCompatDelegate.setDefaultNightMode(Settings.getTheme());
// Do io tasks in new thread
//noinspection deprecation
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... voids) {
// Check no media file
try {
UniFile downloadLocation = Settings.getDownloadLocation();
if (Settings.getMediaScan()) {
CommonOperations.removeNoMediaFile(downloadLocation);
} else {
CommonOperations.ensureNoMediaFile(downloadLocation);
}
} catch (Throwable t) {
t.printStackTrace();
ExceptionUtils.throwIfFatal(t);
IoThreadPoolExecutor.getInstance().execute {
try {
val downloadLocation = Settings.getDownloadLocation()
if (Settings.getMediaScan()) {
CommonOperations.removeNoMediaFile(downloadLocation)
} else {
CommonOperations.ensureNoMediaFile(downloadLocation)
}
// Clear temp files
try {
clearTempDir();
} catch (Throwable t) {
t.printStackTrace();
ExceptionUtils.throwIfFatal(t);
}
return null;
} catch (t: Throwable) {
t.printStackTrace()
ExceptionUtils.throwIfFatal(t)
}
}.executeOnExecutor(IoThreadPoolExecutor.getInstance());
// Check app update
update();
// Update version code
try {
PackageInfo pi = getPackageManager().getPackageInfo(getPackageName(), 0);
Settings.putVersionCode(pi.versionCode);
} catch (PackageManager.NameNotFoundException e) {
// Ignore
// Clear temp files
try {
clearTempDir()
} catch (t: Throwable) {
t.printStackTrace()
ExceptionUtils.throwIfFatal(t)
}
}
mIdGenerator.setNextId(Settings.getInt(KEY_GLOBAL_STUFF_NEXT_ID, 0));
if (DEBUG_PRINT_NATIVE_MEMORY || DEBUG_PRINT_IMAGE_COUNT) {
debugPrint();
}
initialized = true;
theDawnOfNewDay();
mIdGenerator.setNextId(Settings.getInt(KEY_GLOBAL_STUFF_NEXT_ID, 0))
initialized = true
theDawnOfNewDay()
}
private void theDawnOfNewDay() {
private fun theDawnOfNewDay() {
if (!Settings.getRequestNews()) {
return;
return
}
EhCookieStore store = getEhCookieStore(this);
HttpUrl eh = HttpUrl.get(EhUrl.HOST_E);
val store = ehCookieStore
val eh = EhUrl.HOST_E.toHttpUrl()
if (store.contains(eh, EhCookieStore.KEY_IPD_MEMBER_ID) || store.contains(eh, EhCookieStore.KEY_IPD_PASS_HASH)) {
IoThreadPoolExecutor.getInstance().execute(() -> {
String referer = EhUrl.REFERER_E;
Request request = new EhRequestBuilder(EhUrl.HOST_E + "news.php", referer).build();
Call call = getOkHttpClient(this).newCall(request);
if (store.contains(eh, EhCookieStore.KEY_IPD_MEMBER_ID) || store.contains(
eh,
EhCookieStore.KEY_IPD_PASS_HASH
)
) {
IoThreadPoolExecutor.getInstance().execute {
val referer = EhUrl.REFERER_E
val request = EhRequestBuilder(EhUrl.HOST_E + "news.php", referer).build()
val call = okHttpClient.newCall(request)
try {
Response response = call.execute();
ResponseBody responseBody = response.body();
if (responseBody == null) {
return;
}
String body = responseBody.string();
String html = EventPaneParser.parse(body);
val response = call.execute()
val responseBody = response.body
val body = responseBody.string()
val html = EventPaneParser.parse(body)
if (html != null) {
showEventPane(html);
showEventPane(html)
}
} catch (Throwable e) {
e.printStackTrace();
} catch (e: Throwable) {
e.printStackTrace()
}
});
}
}
public void showEventPane(String html) {
Activity activity = getTopActivity();
if (activity != null) {
activity.runOnUiThread(() -> {
AlertDialog dialog = new BaseDialogBuilder(activity)
.setMessage(Html.fromHtml(html))
.setPositiveButton(android.R.string.ok, null)
.create();
dialog.setOnShowListener(d -> {
final View messageView = dialog.findViewById(android.R.id.message);
if (messageView instanceof TextView) {
((TextView) messageView).setMovementMethod(LinkMovementMethod.getInstance());
}
});
try {
dialog.show();
} catch (Throwable t) {
// ignore
}
});
}
}
private void clearTempDir() {
File dir = AppConfig.getTempDir();
if (null != dir) {
FileUtils.deleteContent(dir);
}
dir = AppConfig.getExternalTempDir();
if (null != dir) {
FileUtils.deleteContent(dir);
}
}
private void update() {
int version = Settings.getVersionCode();
if (version < 52) {
Settings.putGuideGallery(true);
}
}
public void clearMemoryCache() {
if (null != mGalleryDetailCache) {
mGalleryDetailCache.evictAll();
}
}
@Override
public void onTrimMemory(int level) {
super.onTrimMemory(level);
if (level >= ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW) {
clearMemoryCache();
}
}
private void debugPrint() {
new Runnable() {
@Override
public void run() {
if (DEBUG_PRINT_NATIVE_MEMORY) {
Log.i(TAG, "Native memory: " + FileUtils.humanReadableByteCount(
Debug.getNativeHeapAllocatedSize(), false));
}
SimpleHandler.getInstance().postDelayed(this, DEBUG_PRINT_INTERVAL);
}
}.run();
}
public int putGlobalStuff(@NonNull Object o) {
int id = mIdGenerator.nextId();
mGlobalStuffMap.put(id, o);
Settings.putInt(KEY_GLOBAL_STUFF_NEXT_ID, mIdGenerator.nextId());
return id;
}
public boolean containGlobalStuff(int id) {
return mGlobalStuffMap.containsKey(id);
}
public Object getGlobalStuff(int id) {
return mGlobalStuffMap.get(id);
}
public Object removeGlobalStuff(int id) {
return mGlobalStuffMap.remove(id);
}
public void removeGlobalStuff(Object o) {
mGlobalStuffMap.values().removeAll(Collections.singleton(o));
}
public void registerActivity(Activity activity) {
mActivityList.add(activity);
}
public void unregisterActivity(Activity activity) {
mActivityList.remove(activity);
}
@Nullable
public EhActivity getTopActivity() {
if (!mActivityList.isEmpty()) {
return (EhActivity) mActivityList.get(mActivityList.size() - 1);
} else {
return null;
}
}
// Avoid crash on some "energy saving" devices
@Override
public ComponentName startService(Intent service) {
try {
return super.startService(service);
} catch (Throwable t) {
t.printStackTrace();
ExceptionUtils.throwIfFatal(t);
return null;
fun showEventPane(html: String) {
val activity = topActivity
activity?.runOnUiThread {
val dialog = BaseDialogBuilder(activity)
.setMessage(Html.fromHtml(html, Html.FROM_HTML_MODE_LEGACY))
.setPositiveButton(android.R.string.ok, null)
.create()
dialog.setOnShowListener {
val messageView = dialog.findViewById<View>(android.R.id.message)
if (messageView is TextView) {
messageView.movementMethod = LinkMovementMethod.getInstance()
}
}
try {
dialog.show()
} catch (t: Throwable) {
// ignore
}
}
}
// Avoid crash on some "energy saving" devices
@Override
public boolean bindService(Intent service, ServiceConnection conn, int flags) {
try {
return super.bindService(service, conn, flags);
} catch (Throwable t) {
t.printStackTrace();
ExceptionUtils.throwIfFatal(t);
return false;
private fun clearTempDir() {
var dir = AppConfig.getTempDir()
if (null != dir) {
FileUtils.deleteContent(dir)
}
dir = AppConfig.getExternalTempDir()
if (null != dir) {
FileUtils.deleteContent(dir)
}
}
// Avoid crash on some "energy saving" devices
@Override
public void unbindService(ServiceConnection conn) {
try {
super.unbindService(conn);
} catch (Throwable t) {
t.printStackTrace();
ExceptionUtils.throwIfFatal(t);
override fun onTrimMemory(level: Int) {
super.onTrimMemory(level)
if (level >= ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW) {
galleryDetailCache.evictAll()
}
}
// Avoid crash on some "energy saving" devices
@Override
public ComponentName startForegroundService(Intent service) {
try {
return super.startForegroundService(service);
} catch (Throwable t) {
t.printStackTrace();
ExceptionUtils.throwIfFatal(t);
return null;
}
fun putGlobalStuff(o: Any): Int {
val id = mIdGenerator.nextId()
mGlobalStuffMap[id] = o
Settings.putInt(KEY_GLOBAL_STUFF_NEXT_ID, mIdGenerator.nextId())
return id
}
static class EhlifecycleObserver implements DefaultLifecycleObserver {
@Override
public void onPause(@NonNull LifecycleOwner owner) {
fun containGlobalStuff(id: Int): Boolean {
return mGlobalStuffMap.containsKey(id)
}
fun getGlobalStuff(id: Int): Any? {
return mGlobalStuffMap[id]
}
fun removeGlobalStuff(id: Int): Any? {
return mGlobalStuffMap.remove(id)
}
fun removeGlobalStuff(o: Any) {
mGlobalStuffMap.values.removeAll(setOf(o))
}
fun registerActivity(activity: Activity) {
mActivityList.add(activity)
}
fun unregisterActivity(activity: Activity) {
mActivityList.remove(activity)
}
internal class EhlifecycleObserver : DefaultLifecycleObserver {
override fun onPause(owner: LifecycleOwner) {
if (!locked)
locked_last_leave_time = System.currentTimeMillis() / 1000;
locked = true;
locked_last_leave_time = System.currentTimeMillis() / 1000
locked = true
}
}
companion object {
private const val KEY_GLOBAL_STUFF_NEXT_ID = "global_stuff_next_id"
var locked = true
var locked_last_leave_time: Long = 0
@JvmStatic
lateinit var application: EhApplication
private set
@JvmStatic
val ehCookieStore by lazy { EhCookieStore(application) }
@JvmStatic
val ehClient by lazy { EhClient(application) }
@JvmStatic
val ehProxySelector by lazy { EhProxySelector() }
@JvmStatic
val okHttpClient by lazy {
val builder = OkHttpClient.Builder()
.cookieJar(ehCookieStore)
.cache(Cache(File(application.cacheDir, "http_cache"), 50L * 1024L * 1024L))
.dns(EhDns())
.proxySelector(ehProxySelector)
if (Settings.getDF()) {
var trustManager: X509TrustManager
try {
val trustManagerFactory = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm()
)
trustManagerFactory.init(null as KeyStore?)
val trustManagers = trustManagerFactory.trustManagers
check(!(trustManagers.size != 1 || trustManagers[0] !is X509TrustManager)) {
"Unexpected default trust managers:" + Arrays.toString(
trustManagers
)
}
trustManager = trustManagers[0] as X509TrustManager
} catch (e: Exception) {
e.printStackTrace()
trustManager = EhX509TrustManager()
}
builder.sslSocketFactory(EhSSLSocketFactory(), trustManager)
}
builder.build()
}
@JvmStatic
val galleryDetailCache by lazy {
LruCache<Long, GalleryDetail>(25).also {
favouriteStatusRouter.addListener { gid, slot ->
it[gid]?.favoriteSlot = slot
}
}
}
@JvmStatic
val spiderInfoCache by lazy {
SimpleDiskCache(
File(application.cacheDir, "spider_info"),
20 * 1024 * 1024
)
}
@JvmStatic
val downloadManager by lazy { DownloadManager(application) }
@JvmStatic
val hosts by lazy { Hosts(application, "hosts.db") }
@JvmStatic
val favouriteStatusRouter by lazy { FavouriteStatusRouter() }
}
}
@@ -491,7 +491,7 @@ public class EhDB {
.createFromFile(file).allowMainThreadQueries().build();
// Download label
DownloadManager manager = EhApplication.getDownloadManager(context);
DownloadManager manager = EhApplication.getDownloadManager();
try {
List<DownloadLabel> downloadLabelList = oldRoomDatabase.downloadLabelDao().list();
manager.addDownloadLabel(downloadLabelList);
@@ -246,7 +246,6 @@ public class Settings {
****** Update
********************/
private static final String KEY_BETA_UPDATE_CHANNEL = "beta_update_channel";
private static final boolean DEFAULT_BETA_UPDATE_CHANNEL = EhApplication.BETA;
private static final String KEY_SKIP_UPDATE_VERSION = "skip_update_version";
private static final int DEFAULT_SKIP_UPDATE_VERSION = 0;
private static final boolean DEFAULT_SAVE_PARSE_ERROR_BODY = true;
@@ -424,14 +423,6 @@ public class Settings {
sSettingsPre.edit().putString(key, Integer.toString(value)).apply();
}
public static int getVersionCode() {
return getInt(KEY_VERSION_CODE, DEFAULT_VERSION_CODE);
}
public static void putVersionCode(int value) {
putInt(KEY_VERSION_CODE, value);
}
@Nullable
public static String getDisplayName() {
return getString(KEY_DISPLAY_NAME, DEFAULT_DISPLAY_NAME);
@@ -1024,10 +1015,6 @@ public class Settings {
return true;
}
public static boolean getBetaUpdateChannel() {
return getBoolean(KEY_BETA_UPDATE_CHANNEL, DEFAULT_BETA_UPDATE_CHANNEL);
}
public static void putBetaUpdateChannel(boolean value) {
putBoolean(KEY_BETA_UPDATE_CHANNEL, value);
}
@@ -61,7 +61,7 @@ public class EhClient {
public EhClient(Context context) {
mRequestThreadPool = IoThreadPoolExecutor.getInstance();
mOkHttpClient = EhApplication.getOkHttpClient(context);
mOkHttpClient = EhApplication.getOkHttpClient();
}
public void execute(EhRequest request) {
@@ -15,7 +15,6 @@
*/
package com.hippo.ehviewer.client
import android.content.Context
import com.hippo.ehviewer.EhApplication
import com.hippo.ehviewer.Hosts
import com.hippo.ehviewer.Settings
@@ -23,8 +22,8 @@ import okhttp3.Dns
import java.net.InetAddress
import java.net.UnknownHostException
class EhDns(context: Context) : Dns {
private val hosts = EhApplication.getHosts(context)
class EhDns : Dns {
private val hosts = EhApplication.hosts
private val builtInHosts: MutableMap<String, List<InetAddress>> = mutableMapOf()
init {
@@ -361,7 +361,7 @@ public class EhEngine {
body = response.body().string();
String html = EventPaneParser.parse(body);
if (html != null) {
EhApplication.getInstance().showEventPane(html);
EhApplication.getApplication().showEventPane(html);
}
return GalleryDetailParser.parse(body);
} catch (Throwable e) {
@@ -260,7 +260,7 @@ public class EhTagDatabase {
}
}
OkHttpClient client = EhApplication.getOkHttpClient(context);
OkHttpClient client = EhApplication.getOkHttpClient();
// Save new sha1
File tempSha1File = new File(dir, sha1Name + ".tmp");
@@ -133,14 +133,14 @@ public class EhUtils {
}
public static void signOut(Context context) {
EhApplication.getEhCookieStore(context).signOut();
EhApplication.getEhCookieStore().signOut();
Settings.putAvatar(null);
Settings.putDisplayName(null);
Settings.putNeedSignIn(true);
}
public static boolean needSignedIn(Context context) {
return Settings.getNeedSignIn() && !EhApplication.getEhCookieStore(context).hasSignedIn();
return Settings.getNeedSignIn() && !EhApplication.getEhCookieStore().hasSignedIn();
}
public static String getSuitableTitle(GalleryInfo gi) {
@@ -67,7 +67,7 @@ class DownloadService : Service(), DownloadManager.DownloadListener {
.setName(getString(R.string.download_service))
.build()
)
mDownloadManager = EhApplication.getDownloadManager(applicationContext)
mDownloadManager = EhApplication.downloadManager
mDownloadManager!!.setDownloadListener(this)
ensureDownloadingBuilder()
mDownloadingBuilder!!.setContentTitle(getString(R.string.download_service))
@@ -40,7 +40,7 @@ class AccountPreference @JvmOverloads constructor(
private var message: String? = null
init {
val store = EhApplication.getEhCookieStore(context)
val store = EhApplication.ehCookieStore
val eCookies = store.getCookies(EhUrl.HOST_E.toHttpUrl())
val exCookies = store.getCookies(EhUrl.HOST_EX.toHttpUrl())
val cookies: MutableList<Cookie> = LinkedList(eCookies)
@@ -55,7 +55,7 @@ public class CleanRedundancyPreference extends TaskPreference {
public ClearTask(@NonNull Context context) {
super(context);
mManager = EhApplication.getDownloadManager(context.getApplicationContext());
mManager = EhApplication.getDownloadManager();
}
// True for cleared
@@ -161,7 +161,7 @@ class ProxyPreference @JvmOverloads constructor(
Settings.putProxyIp(ip)
Settings.putProxyPort(port)
updateSummary(type, ip, port)
EhApplication.getEhProxySelector(getContext()).updateProxy()
EhApplication.ehProxySelector.updateProxy()
dialog.dismiss()
}
}
@@ -74,8 +74,8 @@ public class RestoreDownloadPreference extends TaskPreference {
public RestoreTask(@NonNull Context context) {
super(context);
mManager = EhApplication.getDownloadManager(context.getApplicationContext());
mHttpClient = EhApplication.getOkHttpClient(context.getApplicationContext());
mManager = EhApplication.getDownloadManager();
mHttpClient = EhApplication.getOkHttpClient();
}
private RestoreItem getRestoreItem(UniFile file) {
@@ -58,7 +58,7 @@ public class SignInRequiredPreference extends Preference implements Preference.O
@Override
public boolean onPreferenceClick(Preference preference) {
EhCookieStore store = EhApplication.getEhCookieStore(getContext());
EhCookieStore store = EhApplication.getEhCookieStore();
HttpUrl e = HttpUrl.get(EhUrl.HOST_E);
HttpUrl ex = HttpUrl.get(EhUrl.HOST_EX);
@@ -158,8 +158,8 @@ public final class SpiderQueen implements Runnable {
private volatile int mDownloadPage = -1;
private SpiderQueen(EhApplication application, @NonNull GalleryInfo galleryInfo) {
mHttpClient = EhApplication.getOkHttpClient(application);
mSpiderInfoCache = EhApplication.getSpiderInfoCache(application);
mHttpClient = EhApplication.getOkHttpClient();
mSpiderInfoCache = EhApplication.getSpiderInfoCache();
mGalleryInfo = galleryInfo;
mSpiderDen = new SpiderDen(mGalleryInfo);
@@ -53,7 +53,7 @@ public final class CommonOperations {
EhDB.putLocalFavorites(galleryInfo);
listener.onSuccess(null);
} else if (slot >= 0 && slot <= 9) {
EhClient client = EhApplication.getEhClient(activity);
EhClient client = EhApplication.getEhClient();
EhRequest request = new EhRequest();
request.setMethod(EhClient.METHOD_ADD_FAVORITES);
request.setArgs(galleryInfo.gid, galleryInfo.token, slot, "");
@@ -100,7 +100,7 @@ public final class CommonOperations {
public static void removeFromFavorites(Activity activity, GalleryInfo galleryInfo,
final EhClient.Callback<Void> listener) {
EhDB.removeLocalFavorites(galleryInfo.gid);
EhClient client = EhApplication.getEhClient(activity);
EhClient client = EhApplication.getEhClient();
EhRequest request = new EhRequest();
request.setMethod(EhClient.METHOD_ADD_FAVORITES);
request.setArgs(galleryInfo.gid, galleryInfo.token, -1, "");
@@ -114,13 +114,13 @@ public final class CommonOperations {
public static void startDownload(final MainActivity activity, final List<GalleryInfo> galleryInfos, boolean forceDefault) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
Objects.requireNonNull(EhApplication.getInstance().getTopActivity()).checkAndRequestNotificationPermission();
Objects.requireNonNull(EhApplication.getApplication().getTopActivity()).checkAndRequestNotificationPermission();
}
doStartDownload(activity, galleryInfos, forceDefault);
}
private static void doStartDownload(final MainActivity activity, final List<GalleryInfo> galleryInfos, boolean forceDefault) {
final DownloadManager dm = EhApplication.getDownloadManager(activity);
final DownloadManager dm = EhApplication.getDownloadManager();
LongList toStart = new LongList();
List<GalleryInfo> toAdd = new ArrayList<>();
@@ -31,7 +31,6 @@ import androidx.annotation.StyleRes
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import com.hippo.ehviewer.EhApplication
import com.hippo.ehviewer.EhApplication.locked_last_leave_time
import com.hippo.ehviewer.R
import com.hippo.ehviewer.Settings
import rikka.core.res.resolveColor
@@ -91,7 +90,7 @@ abstract class EhActivity : AppCompatActivity() {
override fun onResume() {
val locked_resume_time = System.currentTimeMillis() / 1000
val locked_delay_time = locked_resume_time - locked_last_leave_time
val locked_delay_time = locked_resume_time - EhApplication.locked_last_leave_time
if (locked_delay_time < Settings.getSecurityDelay() * 60) {
EhApplication.locked = false
} else if (Settings.getSecurity() && isAuthenticationSupported() && EhApplication.locked) {
@@ -305,7 +305,7 @@ public class AdvancedFragment extends BasePreferenceFragment {
}
private void backupFavorite() {
EhClient mClient = EhApplication.getEhClient(requireContext());
EhClient mClient = EhApplication.getEhClient();
FavListUrlBuilder favListUrlBuilder = new FavListUrlBuilder();
favTotal = 0;
favIndex = 1;
@@ -43,7 +43,7 @@ class HostsFragment : BaseFragment(), View.OnClickListener {
private var adapter: HostsAdapter? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
EhApplication.getHosts(requireContext()).apply {
EhApplication.hosts.apply {
hosts = this
data = all
}
@@ -84,7 +84,7 @@ public class MyTagsFragment extends BaseFragment {
// Copy cookies from okhttp cookie store to CookieManager
url = EhUrl.getMyTagsUrl();
EhCookieStore store = EhApplication.getEhCookieStore(requireContext());
EhCookieStore store = EhApplication.getEhCookieStore();
for (Cookie cookie : store.getCookies(HttpUrl.parse(url))) {
cookieManager.setCookie(url, cookie.toString());
}
@@ -91,7 +91,7 @@ public class UConfigFragment extends BaseFragment {
// Copy cookies from okhttp cookie store to CookieManager
url = EhUrl.getUConfigUrl();
EhCookieStore store = EhApplication.getEhCookieStore(requireContext());
EhCookieStore store = EhApplication.getEhCookieStore();
for (Cookie cookie : store.getCookies(HttpUrl.parse(url))) {
cookieManager.setCookie(url, cookie.toString());
}
@@ -142,7 +142,7 @@ public class UConfigFragment extends BaseFragment {
String cookiesString = cookieManager.getCookie(url);
if (cookiesString != null && !cookiesString.isEmpty()) {
EhCookieStore store = EhApplication.getEhCookieStore(requireContext());
EhCookieStore store = EhApplication.getEhCookieStore();
HttpUrl eUrl = HttpUrl.parse(EhUrl.HOST_E);
HttpUrl exUrl = HttpUrl.parse(EhUrl.HOST_EX);
if (eUrl == null || exUrl == null) {
@@ -240,7 +240,7 @@ public class CookieSignInScene extends SolidScene implements EditText.OnEditorAc
EhUtils.signOut(context);
EhCookieStore store = EhApplication.getEhCookieStore(context);
EhCookieStore store = EhApplication.getEhCookieStore();
store.addCookie(newCookie(EhCookieStore.KEY_IPD_MEMBER_ID, id, EhUrl.DOMAIN_E));
store.addCookie(newCookie(EhCookieStore.KEY_IPD_MEMBER_ID, id, EhUrl.DOMAIN_EX));
store.addCookie(newCookie(EhCookieStore.KEY_IPD_PASS_HASH, hash, EhUrl.DOMAIN_E));
@@ -162,7 +162,7 @@ public class DownloadsScene extends ToolbarScene
if (context == null) {
return;
}
List<DownloadLabel> listLabel = EhApplication.getDownloadManager(context).getLabelList();
List<DownloadLabel> listLabel = EhApplication.getDownloadManager().getLabelList();
mLabels = new ArrayList<>(listLabel.size() + 1);
// Add default label name
mLabels.add(getString(R.string.default_download_label_name));
@@ -214,7 +214,7 @@ public class DownloadsScene extends ToolbarScene
Context context = getContext();
AssertUtils.assertNotNull(context);
mDownloadManager = EhApplication.getDownloadManager(context);
mDownloadManager = EhApplication.getDownloadManager();
mDownloadManager.addDownloadInfoListener(this);
if (savedInstanceState == null) {
@@ -233,7 +233,7 @@ public class DownloadsScene extends ToolbarScene
if (null == manager) {
Context context = getContext();
if (null != context) {
manager = EhApplication.getDownloadManager(context);
manager = EhApplication.getDownloadManager();
}
} else {
mDownloadManager = null;
@@ -697,7 +697,7 @@ public class DownloadsScene extends ToolbarScene
break;
}
case 4: {// Move
List<DownloadLabel> labelRawList = EhApplication.getDownloadManager(context).getLabelList();
List<DownloadLabel> labelRawList = EhApplication.getDownloadManager().getLabelList();
List<String> labelList = new ArrayList<>(labelRawList.size() + 1);
labelList.add(getString(R.string.default_download_label_name));
for (int i = 0, n = labelRawList.size(); i < n; i++) {
@@ -906,7 +906,7 @@ public class DownloadsScene extends ToolbarScene
String label = mLabels.get(position);
if (mDownloadManager == null) {
if (context != null) {
mDownloadManager = EhApplication.getDownloadManager(context);
mDownloadManager = EhApplication.getDownloadManager();
}
}
List<DownloadInfo> list = null;
@@ -1040,7 +1040,7 @@ public class DownloadsScene extends ToolbarScene
} else {
label = mLabels[which];
}
EhApplication.getDownloadManager(context).changeLabel(mDownloadInfoList, label);
EhApplication.getDownloadManager().changeLabel(mDownloadInfoList, label);
if (mLabelAdapter != null) {
mLabelAdapter.notifyDataSetChanged();
}
@@ -1162,7 +1162,7 @@ public class DownloadsScene extends ToolbarScene
return;
}
DownloadInfo info = mList.get(position);
holder.thumb.load(EhCacheKeyFactory.getThumbKey(info.gid), info.thumb, true);
holder.thumb.load(EhCacheKeyFactory.getThumbKey(info.gid), info.thumb);
holder.title.setText(EhUtils.getSuitableTitle(info));
holder.uploader.setText(info.uploader);
holder.rating.setRating(info.rating);
@@ -1246,12 +1246,12 @@ public class DownloadsScene extends ToolbarScene
mBuilder.setError(getString(R.string.label_text_is_empty));
} else if (getString(R.string.default_download_label_name).equals(text)) {
mBuilder.setError(getString(R.string.label_text_is_invalid));
} else if (EhApplication.getDownloadManager(context).containLabel(text)) {
} else if (EhApplication.getDownloadManager().containLabel(text)) {
mBuilder.setError(getString(R.string.label_text_exist));
} else {
mBuilder.setError(null);
mDialog.dismiss();
EhApplication.getDownloadManager(context).renameLabel(mOriginalLabel, text);
EhApplication.getDownloadManager().renameLabel(mOriginalLabel, text);
if (mLabelAdapter != null) {
initLabels();
mLabelAdapter.notifyDataSetChanged();
@@ -1286,12 +1286,12 @@ public class DownloadsScene extends ToolbarScene
mBuilder.setError(getString(R.string.label_text_is_empty));
} else if (getString(R.string.default_download_label_name).equals(text)) {
mBuilder.setError(getString(R.string.label_text_is_invalid));
} else if (EhApplication.getDownloadManager(context).containLabel(text)) {
} else if (EhApplication.getDownloadManager().containLabel(text)) {
mBuilder.setError(getString(R.string.label_text_exist));
} else {
mBuilder.setError(null);
mDialog.dismiss();
EhApplication.getDownloadManager(context).addLabel(text);
EhApplication.getDownloadManager().addLabel(text);
initLabels();
if (mLabelAdapter != null && mLabels != null) {
mLabelAdapter.notifyItemInserted(mLabels.size() - 1);
@@ -1317,7 +1317,7 @@ public class DownloadsScene extends ToolbarScene
return false;
}
EhApplication.getDownloadManager(context).moveLabel(fromPosition - 1, toPosition - 1);
EhApplication.getDownloadManager().moveLabel(fromPosition - 1, toPosition - 1);
final String item = mLabels.remove(fromPosition);
mLabels.add(toPosition, item);
mLabelAdapter.notifyDataSetChanged();
@@ -188,7 +188,7 @@ public class FavoritesScene extends BaseScene implements
Context context = getContext();
AssertUtils.assertNotNull(context);
mClient = EhApplication.getEhClient(context);
mClient = EhApplication.getEhClient();
mFavCatArray = Settings.getFavCat();
mFavCountArray = Settings.getFavCount();
mFavLocalCount = Settings.getFavLocalCount();
@@ -85,7 +85,7 @@ abstract class GalleryAdapter extends RecyclerView.Adapter<GalleryHolder> {
setType(type);
mDownloadManager = EhApplication.getDownloadManager(inflater.getContext());
mDownloadManager = EhApplication.getDownloadManager();
}
private void adjustPaddings() {
@@ -278,7 +278,7 @@ public final class GalleryCommentsScene extends ToolbarScene
.setArgs(mGalleryDetail.apiUid, mGalleryDetail.apiKey, mGalleryDetail.gid, mGalleryDetail.token, id, vote)
.setCallback(new VoteCommentListener(context,
activity.getStageId(), getTag()));
EhApplication.getEhClient(context).execute(request);
EhApplication.getEhClient().execute(request);
}
@SuppressLint("InflateParams")
@@ -408,7 +408,7 @@ public final class GalleryCommentsScene extends ToolbarScene
.setMethod(EhClient.METHOD_GET_GALLERY_DETAIL)
.setArgs(url)
.setCallback(new RefreshCommentListener(activity, activity.getStageId(), getTag()));
EhApplication.getEhClient(activity).execute(request);
EhApplication.getEhClient().execute(request);
}
}
@@ -591,7 +591,7 @@ public final class GalleryCommentsScene extends ToolbarScene
.setArgs(url, comment, mCommentId != 0 ? Long.toString(mCommentId) : null)
.setCallback(new CommentGalleryListener(context,
activity.getStageId(), getTag(), mCommentId));
EhApplication.getEhClient(context).execute(request);
EhApplication.getEhClient().execute(request);
hideSoftInput();
hideEditPanel(true);
}
@@ -709,7 +709,7 @@ public final class GalleryCommentsScene extends ToolbarScene
.setMethod(EhClient.METHOD_GET_GALLERY_DETAIL)
.setArgs(url)
.setCallback(new RefreshCommentListener(activity, activity.getStageId(), getTag()));
EhApplication.getEhClient(activity).execute(request);
EhApplication.getEhClient().execute(request);
}
}
}
@@ -555,7 +555,7 @@ public class GalleryDetailScene extends CollapsingToolbarScene implements View.O
if (gid != -1) {
Context context = getContext();
AssertUtils.assertNotNull(context);
mDownloadState = EhApplication.getDownloadManager(context).getDownloadState(gid);
mDownloadState = EhApplication.getDownloadManager().getDownloadState(gid);
} else {
mDownloadState = DownloadInfo.STATE_INVALID;
}
@@ -663,7 +663,7 @@ public class GalleryDetailScene extends CollapsingToolbarScene implements View.O
adjustViewVisibility(STATE_FAILED, false);
}
EhApplication.getDownloadManager(context).addDownloadInfoListener(this);
EhApplication.getDownloadManager().addDownloadInfoListener(this);
return view;
}
@@ -674,7 +674,7 @@ public class GalleryDetailScene extends CollapsingToolbarScene implements View.O
Context context = getContext();
AssertUtils.assertNotNull(context);
EhApplication.getDownloadManager(context).removeDownloadInfoListener(this);
EhApplication.getDownloadManager().removeDownloadInfoListener(this);
mTip = null;
mViewTransition = null;
@@ -737,7 +737,7 @@ public class GalleryDetailScene extends CollapsingToolbarScene implements View.O
}
// Get from cache
mGalleryDetail = EhApplication.getGalleryDetailCache(context).get(gid);
mGalleryDetail = EhApplication.getGalleryDetailCache().get(gid);
if (mGalleryDetail != null) {
return true;
}
@@ -767,7 +767,7 @@ public class GalleryDetailScene extends CollapsingToolbarScene implements View.O
.setMethod(EhClient.METHOD_GET_GALLERY_DETAIL)
.setArgs(url)
.setCallback(callback);
EhApplication.getEhClient(context).execute(request);
EhApplication.getEhClient().execute(request);
return true;
}
@@ -878,6 +878,7 @@ public class GalleryDetailScene extends CollapsingToolbarScene implements View.O
Resources resources = getResources();
mThumb.load(EhCacheKeyFactory.getThumbKey(gd.gid), gd.thumb);
setTitle(EhUtils.getSuitableTitle(gd));
mUploader.setText(gd.uploader);
mUploader.setAlpha(gd.disowned ? .5f : 1f);
@@ -1148,7 +1149,7 @@ public class GalleryDetailScene extends CollapsingToolbarScene implements View.O
} else if (mDownload == v) {
GalleryInfo galleryInfo = getGalleryInfo();
if (galleryInfo != null) {
if (EhApplication.getDownloadManager(context).getDownloadState(galleryInfo.gid) == DownloadInfo.STATE_INVALID) {
if (EhApplication.getDownloadManager().getDownloadState(galleryInfo.gid) == DownloadInfo.STATE_INVALID) {
CommonOperations.startDownload(activity, galleryInfo, false);
} else {
CheckBoxDialogBuilder builder = new CheckBoxDialogBuilder(context,
@@ -1156,7 +1157,7 @@ public class GalleryDetailScene extends CollapsingToolbarScene implements View.O
getString(R.string.download_remove_dialog_check_text),
Settings.getRemoveImageFiles());
DeleteDialogHelper helper = new DeleteDialogHelper(
EhApplication.getDownloadManager(context), galleryInfo, builder);
EhApplication.getDownloadManager(), galleryInfo, builder);
builder.setTitle(R.string.download_remove_dialog_title)
.setPositiveButton(android.R.string.ok, helper)
.show();
@@ -1424,7 +1425,7 @@ public class GalleryDetailScene extends CollapsingToolbarScene implements View.O
.setArgs(mGalleryDetail.apiUid, mGalleryDetail.apiKey, mGalleryDetail.gid, mGalleryDetail.token, tag, vote)
.setCallback(new VoteTagListener(context,
activity.getStageId(), getTag()));
EhApplication.getEhClient(context).execute(request);
EhApplication.getEhClient().execute(request);
}
@Override
@@ -1527,7 +1528,7 @@ public class GalleryDetailScene extends CollapsingToolbarScene implements View.O
return;
}
int downloadState = EhApplication.getDownloadManager(context).getDownloadState(gid);
int downloadState = EhApplication.getDownloadManager().getDownloadState(gid);
if (downloadState == mDownloadState) {
return;
}
@@ -1645,7 +1646,7 @@ public class GalleryDetailScene extends CollapsingToolbarScene implements View.O
getApplication().removeGlobalStuff(this);
// Put gallery detail to cache
EhApplication.getGalleryDetailCache(getApplication()).put(result.gid, result);
EhApplication.getGalleryDetailCache().put(result.gid, result);
// Add history
EhDB.putHistoryInfo(result);
@@ -1725,7 +1726,7 @@ public class GalleryDetailScene extends CollapsingToolbarScene implements View.O
scene.onRateGallerySuccess(result);
} else {
// Update rating in cache
GalleryDetail gd = EhApplication.getGalleryDetailCache(getApplication()).get(mGid);
GalleryDetail gd = EhApplication.getGalleryDetailCache().get(mGid);
if (gd != null) {
gd.rating = result.rating;
gd.ratingCount = result.ratingCount;
@@ -1854,7 +1855,7 @@ public class GalleryDetailScene extends CollapsingToolbarScene implements View.O
mRequest = new EhRequest().setMethod(EhClient.METHOD_ARCHIVE_LIST)
.setArgs(url, mGid, mToken)
.setCallback(this);
EhApplication.getEhClient(context).execute(mRequest);
EhApplication.getEhClient().execute(mRequest);
} else {
bind(mArchiveList);
}
@@ -1893,7 +1894,7 @@ public class GalleryDetailScene extends CollapsingToolbarScene implements View.O
request.setMethod(EhClient.METHOD_DOWNLOAD_ARCHIVE);
request.setArgs(mGalleryDetail.gid, mGalleryDetail.token, mArchiveFormParamOr, res);
request.setCallback(new DownloadArchiveListener(context, activity.getStageId(), getTag()));
EhApplication.getEhClient(context).execute(request);
EhApplication.getEhClient().execute(request);
}
if (mDialog != null) {
@@ -1971,7 +1972,7 @@ public class GalleryDetailScene extends CollapsingToolbarScene implements View.O
mRequest = new EhRequest().setMethod(EhClient.METHOD_GET_TORRENT_LIST)
.setArgs(url, mGid, mToken)
.setCallback(this);
EhApplication.getEhClient(context).execute(mRequest);
EhApplication.getEhClient().execute(mRequest);
} else {
bind(mTorrentList);
}
@@ -2012,7 +2013,7 @@ public class GalleryDetailScene extends CollapsingToolbarScene implements View.O
FileUtils.sanitizeFilename(name + ".torrent"));
r.allowScanningByMediaScanner();
r.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
r.addRequestHeader("Cookie", EhApplication.getEhCookieStore(context).getCookieHeader(HttpUrl.get(url)));
r.addRequestHeader("Cookie", EhApplication.getEhCookieStore().getCookieHeader(HttpUrl.get(url)));
DownloadManager dm = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
if (dm != null) {
try {
@@ -2107,7 +2108,7 @@ public class GalleryDetailScene extends CollapsingToolbarScene implements View.O
mGalleryDetail.gid, mGalleryDetail.token, mRatingBar.getRating())
.setCallback(new RateGalleryListener(context,
activity.getStageId(), getTag(), mGalleryDetail.gid));
EhApplication.getEhClient(context).execute(request);
EhApplication.getEhClient().execute(request);
}
}
@@ -339,9 +339,9 @@ public final class GalleryListScene extends BaseScene
Context context = getContext();
AssertUtils.assertNotNull(context);
mClient = EhApplication.getEhClient(context);
mDownloadManager = EhApplication.getDownloadManager(context);
mFavouriteStatusRouter = EhApplication.getFavouriteStatusRouter(context);
mClient = EhApplication.getEhClient();
mDownloadManager = EhApplication.getDownloadManager();
mFavouriteStatusRouter = EhApplication.getFavouriteStatusRouter();
mDownloadInfoListener = new DownloadManager.DownloadInfoListener() {
@Override
@@ -1030,7 +1030,7 @@ public final class GalleryListScene extends BaseScene
}
break;
case 3: // Move
List<DownloadLabel> labelRawList = EhApplication.getDownloadManager(context).getLabelList();
List<DownloadLabel> labelRawList = EhApplication.getDownloadManager().getLabelList();
List<String> labelList = new ArrayList<>(labelRawList.size() + 1);
labelList.add(getString(R.string.default_download_label_name));
for (int i = 0, n = labelRawList.size(); i < n; i++) {
@@ -1571,7 +1571,7 @@ public final class GalleryListScene extends BaseScene
mRecyclerView.outOfCustomChoiceMode();
}
DownloadManager downloadManager = EhApplication.getDownloadManager(context);
DownloadManager downloadManager = EhApplication.getDownloadManager();
DownloadInfo downloadInfo = downloadManager.getDownloadInfo(mGi.gid);
if (downloadInfo == null) {
return;
@@ -96,7 +96,7 @@ public class GalleryPreviewsScene extends ToolbarScene {
Context context = getContext();
AssertUtils.assertNotNull(context);
mClient = EhApplication.getEhClient(context);
mClient = EhApplication.getEhClient();
if (savedInstanceState == null) {
onInit();
} else {
@@ -72,9 +72,7 @@ class HistoryScene : ToolbarScene() {
}
})
}
private val mDownloadManager: DownloadManager by lazy {
EhApplication.getDownloadManager(requireContext())
}
private val mDownloadManager = EhApplication.downloadManager
private val mDownloadInfoListener: DownloadInfoListener by lazy {
object : DownloadInfoListener {
override fun onAdd(info: DownloadInfo, list: List<DownloadInfo>, position: Int) {
@@ -99,9 +97,7 @@ class HistoryScene : ToolbarScene() {
override fun onUpdateLabels() {}
}
}
private val mFavouriteStatusRouter: FavouriteStatusRouter by lazy {
EhApplication.getFavouriteStatusRouter(requireContext())
}
private val mFavouriteStatusRouter = EhApplication.favouriteStatusRouter
private val mFavouriteStatusRouterListener: FavouriteStatusRouter.Listener by lazy {
FavouriteStatusRouter.Listener { _: Long, _: Int ->
mAdapter.notifyDataSetChanged()
@@ -302,7 +298,7 @@ class HistoryScene : ToolbarScene() {
}
3 -> {
val labelRawList = EhApplication.getDownloadManager(context).labelList
val labelRawList = EhApplication.downloadManager.labelList
val labelList: MutableList<String> = ArrayList(labelRawList.size + 1)
labelList.add(getString(R.string.default_download_label_name))
var i = 0
@@ -373,7 +369,7 @@ class HistoryScene : ToolbarScene() {
private val mGi: GalleryInfo
) : DialogInterface.OnClickListener {
override fun onClick(dialog: DialogInterface, which: Int) {
val downloadManager = EhApplication.getDownloadManager(requireContext())
val downloadManager = EhApplication.downloadManager
val downloadInfo = downloadManager.getDownloadInfo(mGi.gid) ?: return
val label = if (which == 0) null else mLabels[which]
downloadManager.changeLabel(listOf(downloadInfo), label)
@@ -99,7 +99,7 @@ public final class ProgressScene extends BaseScene implements View.OnClickListen
.setArgs(mGid, mPToken, mPage)
.setCallback(new GetGalleryTokenListener(context,
activity.getStageId(), getTag()));
EhApplication.getEhClient(context).execute(request);
EhApplication.getEhClient().execute(request);
return true;
}
return false;
@@ -50,7 +50,7 @@ public class SelectSiteScene extends SolidScene implements View.OnClickListener
View view = inflater.inflate(R.layout.scene_select_site, container, false);
mButtonGroup = (MaterialButtonToggleGroup) ViewUtils.$$(view, R.id.button_group);
if (EhApplication.getEhCookieStore(requireContext()).hasSignedIn()) {
if (EhApplication.getEhCookieStore().hasSignedIn()) {
((MaterialButton) view.findViewById(R.id.site_ex)).setChecked(true);
} else {
((MaterialButton) view.findViewById(R.id.site_e)).setChecked(true);
@@ -289,7 +289,7 @@ public final class SignInScene extends SolidScene implements EditText.OnEditorAc
.setMethod(EhClient.METHOD_SIGN_IN)
.setArgs(username, password)
.setCallback(callback);
EhApplication.getEhClient(context).execute(request);
EhApplication.getEhClient().execute(request);
mSigningIn = true;
}
@@ -310,7 +310,7 @@ public final class SignInScene extends SolidScene implements EditText.OnEditorAc
EhRequest request = new EhRequest()
.setMethod(EhClient.METHOD_GET_PROFILE)
.setCallback(callback);
EhApplication.getEhClient(context).execute(request);
EhApplication.getEhClient().execute(request);
}
private void redirectTo() {
@@ -341,7 +341,7 @@ public final class SignInScene extends SolidScene implements EditText.OnEditorAc
return;
}
if (EhApplication.getEhCookieStore(context).hasSignedIn()) {
if (EhApplication.getEhCookieStore().hasSignedIn()) {
getProfile();
} else {
mSigningIn = false;
@@ -118,7 +118,7 @@ public class WebViewSignInScene extends SolidScene {
}
private void addCookie(Context context, String domain, Cookie cookie) {
EhApplication.getEhCookieStore(context).addCookie(EhCookieStore.newCookie(cookie, domain, true, true, true));
EhApplication.getEhCookieStore().addCookie(EhCookieStore.newCookie(cookie, domain, true, true, true));
}
@Override
@@ -51,11 +51,11 @@ abstract class GalleryInfoContentHelper : ContentHelper<GalleryInfo?>() {
info.favoriteSlot = slot
}
}
EhApplication.getFavouriteStatusRouter().addListener(listener)
EhApplication.favouriteStatusRouter.addListener(listener)
}
fun destroy() {
EhApplication.getFavouriteStatusRouter().removeListener(listener)
EhApplication.favouriteStatusRouter.removeListener(listener)
}
override fun onAddData(data: GalleryInfo?) {
@@ -100,7 +100,7 @@ abstract class GalleryInfoContentHelper : ContentHelper<GalleryInfo?>() {
val bundle = super.saveInstanceState(superState) as Bundle
// TODO It's a bad design
val router = EhApplication.getFavouriteStatusRouter()
val router = EhApplication.favouriteStatusRouter
val id = router.saveDataMap(map)
bundle.putInt(KEY_DATA_MAP, id)
bundle.putInt(KEY_MIN_GID, minGid)
@@ -112,7 +112,7 @@ abstract class GalleryInfoContentHelper : ContentHelper<GalleryInfo?>() {
val bundle = state as Bundle
val id = bundle.getInt(KEY_DATA_MAP, IntIdGenerator.INVALID_ID)
if (id != IntIdGenerator.INVALID_ID) {
val router = EhApplication.getFavouriteStatusRouter()
val router = EhApplication.favouriteStatusRouter
val map = router.restoreDataMap(id)
if (map != null) {
this.map = map
@@ -14,310 +14,207 @@
* limitations under the License.
*/
package com.hippo.widget;
package com.hippo.widget
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.AnimatedImageDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.TransitionDrawable;
import android.util.AttributeSet;
import android.view.View;
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Drawable
import android.graphics.drawable.TransitionDrawable
import android.util.AttributeSet
import android.view.View
import androidx.annotation.IntDef
import androidx.core.content.ContextCompat
import coil.imageLoader
import coil.request.Disposable
import coil.request.ImageRequest
import com.hippo.drawable.PreciselyClipDrawable
import com.hippo.ehviewer.R
import androidx.annotation.DrawableRes;
import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import com.hippo.drawable.PreciselyClipDrawable;
import com.hippo.ehviewer.R;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import coil.Coil;
import coil.request.Disposable;
import coil.request.ImageRequest;
public class LoadImageView extends FixedAspectImageView implements View.OnClickListener, View.OnLongClickListener, Animatable {
public static final int RETRY_TYPE_NONE = 0;
public static final int RETRY_TYPE_CLICK = 1;
public static final int RETRY_TYPE_LONG_CLICK = 2;
private static final String TAG = LoadImageView.class.getSimpleName();
private String mKey;
private String mUrl;
private boolean mUseNetwork;
private int mOffsetX = Integer.MIN_VALUE;
private int mOffsetY = Integer.MIN_VALUE;
private int mClipWidth = Integer.MIN_VALUE;
private int mClipHeight = Integer.MIN_VALUE;
private int mRetryType;
private boolean mFailed;
private boolean mLoadFromDrawable = false;
private Disposable task = null;
public LoadImageView(Context context) {
super(context);
init(context, null, 0);
}
public LoadImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs, 0);
}
public LoadImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context, attrs, defStyle);
}
private void init(Context context, AttributeSet attrs, int defStyleAttr) {
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.LoadImageView, defStyleAttr, 0);
setRetryType(a.getInt(R.styleable.LoadImageView_retryType, 0));
a.recycle();
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if (!mLoadFromDrawable) {
if (mFailed) {
onFailure();
} else if (task != null && task.isDisposed()) {
load(mKey, mUrl, mUseNetwork);
open class LoadImageView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : FixedAspectImageView(context, attrs, defStyleAttr), View.OnClickListener,
View.OnLongClickListener {
private var mRequest: ImageRequest? = null
private var mOffsetX = Integer.MIN_VALUE
private var mOffsetY = Integer.MIN_VALUE
private var mClipWidth = Integer.MIN_VALUE
private var mClipHeight = Integer.MIN_VALUE
private var mRetryType: Int = 0
private var mFailed: Boolean = false
private var task: Disposable? = null
private val imageDrawable: Drawable?
get() {
var drawable = drawable
if (drawable is TransitionDrawable) {
if (drawable.numberOfLayers == 2) {
drawable = drawable.getDrawable(1)
}
}
}
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (!mLoadFromDrawable) {
if (task != null && !task.isDisposed()) {
// Cancel
task.dispose();
// Clear drawable
clearDrawable();
if (drawable is PreciselyClipDrawable) {
drawable = drawable.wrappedDrawable
}
return drawable
}
init {
val a = context.obtainStyledAttributes(attrs, R.styleable.LoadImageView, defStyleAttr, 0)
setRetryType(a.getInt(R.styleable.LoadImageView_retryType, 0))
a.recycle()
}
private Drawable getImageDrawable() {
Drawable drawable = getDrawable();
if (drawable instanceof TransitionDrawable transitionDrawable) {
if (transitionDrawable.getNumberOfLayers() == 2) {
drawable = transitionDrawable.getDrawable(1);
}
}
if (drawable instanceof PreciselyClipDrawable) {
drawable = ((PreciselyClipDrawable) drawable).getWrappedDrawable();
}
return drawable;
override fun onAttachedToWindow() {
super.onAttachedToWindow()
if (mFailed) onFailure()
else task?.run { if (isDisposed) reload() }
}
private void clearDrawable() {
// Set drawable null
setImageDrawable(null);
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
task?.run { if (!isDisposed) dispose() }
clearDrawable()
}
private void clearRetry() {
private fun clearDrawable() {
setImageDrawable(null)
}
private fun clearRetry() {
if (mRetryType == RETRY_TYPE_CLICK) {
setOnClickListener(null);
setClickable(false);
setOnClickListener(null)
isClickable = false
} else if (mRetryType == RETRY_TYPE_LONG_CLICK) {
setOnLongClickListener(null);
setLongClickable(false);
setOnLongClickListener(null)
isLongClickable = false
}
}
public void setRetryType(@RetryType int retryType) {
private fun setRetryType(@RetryType retryType: Int) {
if (mRetryType != retryType) {
int oldRetryType = mRetryType;
mRetryType = retryType;
val oldRetryType = mRetryType
mRetryType = retryType
if (mFailed) {
if (oldRetryType == RETRY_TYPE_CLICK) {
setOnClickListener(null);
setClickable(false);
setOnClickListener(null)
isClickable = false
} else if (oldRetryType == RETRY_TYPE_LONG_CLICK) {
setOnLongClickListener(null);
setLongClickable(false);
setOnLongClickListener(null)
isLongClickable = false
}
if (retryType == RETRY_TYPE_CLICK) {
setOnClickListener(this);
setOnClickListener(this)
} else if (retryType == RETRY_TYPE_LONG_CLICK) {
setOnLongClickListener(this);
setOnLongClickListener(this)
}
}
}
}
public void setClip(int offsetX, int offsetY, int clipWidth, int clipHeight) {
mOffsetX = offsetX;
mOffsetY = offsetY;
mClipWidth = clipWidth;
mClipHeight = clipHeight;
fun setClip(offsetX: Int, offsetY: Int, clipWidth: Int, clipHeight: Int) {
mOffsetX = offsetX
mOffsetY = offsetY
mClipWidth = clipWidth
mClipHeight = clipHeight
}
public void resetClip() {
mOffsetX = Integer.MIN_VALUE;
mOffsetY = Integer.MIN_VALUE;
mClipWidth = Integer.MIN_VALUE;
mClipHeight = Integer.MIN_VALUE;
fun resetClip() {
mOffsetX = Integer.MIN_VALUE
mOffsetY = Integer.MIN_VALUE
mClipWidth = Integer.MIN_VALUE
mClipHeight = Integer.MIN_VALUE
}
public void load(String key, String url) {
load(key, url, true);
fun load(key: String, url: String) {
if ((mRequest?.data as? String?) == url)
return
mFailed = false
clearRetry()
mRequest =
ImageRequest.Builder(context).data(url).memoryCacheKey(key).diskCacheKey(key).target(
{ onWait() },
{ onFailure() },
{ onGetValue(it) }
).build().also { load(it) }
}
public void load(String key, String url, boolean useNetwork) {
if (url == null || (key == null)) {
return;
}
mFailed = false;
clearRetry();
mKey = key;
mUrl = url;
mUseNetwork = useNetwork;
var imageLoader = Coil.imageLoader(getContext());
var request = new ImageRequest.Builder(getContext()).data(url).memoryCacheKey(key).diskCacheKey(key).target(
drawable -> {
onWait();
return null;
},
drawable -> {
onFailure();
return null;
},
drawable -> {
onGetValue(drawable);
return null;
}
).build();
task = imageLoader.enqueue(request);
fun load(request: ImageRequest) {
task = context.imageLoader.enqueue(request)
}
public void load(Drawable drawable) {
unload();
onPreSetImageDrawable(drawable, true);
setImageDrawable(drawable);
private fun reload() {
mRequest?.let { load(it) }
}
public void load(@DrawableRes int id) {
unload();
mLoadFromDrawable = true;
onPreSetImageResource(id, true);
setImageResource(id);
private fun onWait() {
mFailed = false
clearDrawable()
}
public void unload() {
task.dispose();
mKey = null;
mUrl = null;
clearDrawable();
}
public void onWait() {
clearDrawable();
}
public void onGetValue(Drawable drawable) {
clearDrawable();
private fun onGetValue(drawable: Drawable) {
var drawable = drawable
clearDrawable()
if (Integer.MIN_VALUE != mOffsetX) {
drawable = new PreciselyClipDrawable(drawable, mOffsetX, mOffsetY, mClipWidth, mClipHeight);
drawable = PreciselyClipDrawable(drawable, mOffsetX, mOffsetY, mClipWidth, mClipHeight)
}
onPreSetImageDrawable(drawable, true);
if (isShown()) {
Drawable[] layers = new Drawable[2];
layers[0] = new ColorDrawable(Color.TRANSPARENT);
layers[1] = drawable;
TransitionDrawable transitionDrawable = new TransitionDrawable(layers);
setImageDrawable(transitionDrawable);
transitionDrawable.startTransition(300);
onPreSetImageDrawable(drawable, true)
if (isShown) {
val layers = arrayOfNulls<Drawable>(2)
layers[0] = ColorDrawable(Color.TRANSPARENT)
layers[1] = drawable
val transitionDrawable = TransitionDrawable(layers)
setImageDrawable(transitionDrawable)
transitionDrawable.startTransition(300)
} else {
setImageDrawable(drawable);
setImageDrawable(drawable)
}
}
public void onFailure() {
mFailed = true;
clearDrawable();
Drawable drawable = ContextCompat.getDrawable(getContext(), R.drawable.image_failed);
onPreSetImageDrawable(drawable, true);
setImageDrawable(drawable);
if (mRetryType == RETRY_TYPE_CLICK) {
setOnClickListener(this);
} else if (mRetryType == RETRY_TYPE_LONG_CLICK) {
setOnLongClickListener(this);
} else {
// Can't retry, so release
mKey = null;
mUrl = null;
fun onFailure() {
mFailed = true
clearDrawable()
val drawable = ContextCompat.getDrawable(context, R.drawable.image_failed)
onPreSetImageDrawable(drawable, true)
setImageDrawable(drawable)
when (mRetryType) {
RETRY_TYPE_CLICK -> {
setOnClickListener(this)
}
RETRY_TYPE_LONG_CLICK -> {
setOnLongClickListener(this)
}
else -> {
mRequest = null
}
}
}
public void onCancel() {
mFailed = false;
override fun onClick(v: View) {
reload()
}
@Override
public void start() {
Drawable drawable = getImageDrawable();
if (drawable instanceof AnimatedImageDrawable animatedImageDrawable) {
animatedImageDrawable.start();
}
override fun onLongClick(v: View): Boolean {
reload()
return true
}
@Override
public void stop() {
Drawable drawable = getImageDrawable();
if (drawable instanceof AnimatedImageDrawable animatedImageDrawable) {
animatedImageDrawable.stop();
}
}
open fun onPreSetImageDrawable(drawable: Drawable?, isTarget: Boolean) {}
@Override
public boolean isRunning() {
Drawable drawable = getImageDrawable();
if (drawable instanceof AnimatedImageDrawable animatedImageDrawable) {
return animatedImageDrawable.isRunning();
} else {
return false;
}
}
open fun onPreSetImageResource(resId: Int, isTarget: Boolean) {}
@Override
public void onClick(@NonNull View v) {
load(mKey, mUrl, true);
}
@IntDef(RETRY_TYPE_NONE, RETRY_TYPE_CLICK, RETRY_TYPE_LONG_CLICK)
@Retention(AnnotationRetention.SOURCE)
private annotation class RetryType
@Override
public boolean onLongClick(@NonNull View v) {
load(mKey, mUrl, true);
return true;
}
public void onPreSetImageDrawable(Drawable drawable, boolean isTarget) {
}
public void onPreSetImageResource(int resId, boolean isTarget) {
}
@IntDef({RETRY_TYPE_NONE, RETRY_TYPE_CLICK, RETRY_TYPE_LONG_CLICK})
@Retention(RetentionPolicy.SOURCE)
private @interface RetryType {
companion object {
const val RETRY_TYPE_NONE = 0
const val RETRY_TYPE_CLICK = 1
const val RETRY_TYPE_LONG_CLICK = 2
}
}