[FIX] 保存到相冊, 登錄頁網絡狀態顯示.

This commit is contained in:
世界 2020-04-10 03:02:38 +08:00
parent 3912dd2352
commit a3a82b2696
No known key found for this signature in database
GPG Key ID: CD109927C34A63C4
14 changed files with 191 additions and 139 deletions

View File

@ -160,10 +160,12 @@ android {
}
debug {
storeFile project.file('debug.keystore')
storePassword "android"
keyAlias "androiddebugkey"
keyPassword "android"
}
}

View File

@ -2089,11 +2089,12 @@ public class AndroidUtilities {
public static File generatePicturePath(boolean secretChat, String ext) {
try {
File storageDir = getAlbumDir(secretChat);
File dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
FileUtil.initDir(dir);
Date date = new Date();
date.setTime(System.currentTimeMillis() + Utilities.random.nextInt(1000) + 1);
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss_SSS", Locale.US).format(date);
return new File(storageDir, "IMG_" + timeStamp + "." + (TextUtils.isEmpty(ext) ? "jpg" : ext));
return new File(dir, "NekoX/IMG_" + timeStamp + "." + (TextUtils.isEmpty(ext) ? "jpg" : ext));
} catch (Exception e) {
FileLog.e(e);
}
@ -2160,11 +2161,12 @@ public class AndroidUtilities {
public static File generateVideoPath(boolean secretChat) {
try {
File storageDir = getAlbumDir(secretChat);
File dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES);
FileUtil.initDir(dir);
Date date = new Date();
date.setTime(System.currentTimeMillis() + Utilities.random.nextInt(1000) + 1);
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss_SSS", Locale.US).format(date);
return new File(storageDir, "VID_" + timeStamp + ".mp4");
return new File(dir, "NekoX/VID_" + timeStamp + ".mp4");
} catch (Exception e) {
FileLog.e(e);
}

View File

@ -47,7 +47,7 @@ import tw.nekomimi.nekogram.utils.FileUtil;
import tw.nekomimi.nekogram.utils.ProxyUtil;
import tw.nekomimi.nekogram.utils.ZipUtil;
public class ApplicationLoader extends Application implements Thread.UncaughtExceptionHandler {
public class ApplicationLoader extends Application {
@SuppressLint("StaticFieldLeak")
public static volatile Context applicationContext;
@ -201,8 +201,6 @@ public class ApplicationLoader extends Application implements Thread.UncaughtExc
@Override
public void onCreate() {
Thread.setDefaultUncaughtExceptionHandler(this);
try {
applicationContext = getApplicationContext();
} catch (Throwable ignore) {
@ -223,13 +221,6 @@ public class ApplicationLoader extends Application implements Thread.UncaughtExc
AndroidUtilities.runOnUIThread(ApplicationLoader::startPushService);
}
@Override
public void uncaughtException(@NonNull Thread t, @NonNull Throwable e) {
FileLog.e("[APP] uncaughtException in thread " + t,e);
}
@Override
public void onTerminate() {
super.onTerminate();

View File

@ -17,7 +17,7 @@ public class BuildVars {
public static boolean DEBUG_VERSION = false;
public static boolean DEBUG_PRIVATE_VERSION = false;
public static boolean LOGS_ENABLED = false;
public static boolean LOGS_ENABLED = true;
public static boolean USE_CLOUD_STRINGS = true;
public static int BUILD_VERSION;
@ -42,9 +42,8 @@ public class BuildVars {
static {
if (ApplicationLoader.applicationContext != null) {
SharedPreferences sharedPreferences = ApplicationLoader.applicationContext.getSharedPreferences("systemConfig", Context.MODE_PRIVATE);
LOGS_ENABLED = sharedPreferences.getBoolean("logsEnabled", DEBUG_VERSION);
DEBUG_VERSION = LOGS_ENABLED;
DEBUG_PRIVATE_VERSION = LOGS_ENABLED;
DEBUG_VERSION = sharedPreferences.getBoolean("logsEnabled", DEBUG_VERSION);
DEBUG_PRIVATE_VERSION = DEBUG_VERSION;
}
}
}

View File

@ -52,10 +52,11 @@ import android.view.View;
import android.view.WindowManager;
import android.widget.FrameLayout;
import androidx.core.content.FileProvider;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout;
import com.google.android.exoplayer2.util.Log;
import org.telegram.messenger.audioinfo.AudioInfo;
import org.telegram.messenger.video.MediaCodecVideoConvertor;
@ -87,14 +88,20 @@ import java.util.Timer;
import java.util.TimerTask;
import tw.nekomimi.nekogram.NekoXConfig;
import tw.nekomimi.nekogram.utils.FileUtil;
public class MediaController implements AudioManager.OnAudioFocusChangeListener, NotificationCenter.NotificationCenterDelegate, SensorEventListener {
private native int startRecord(String path, int sampleRate);
private native int writeFrame(ByteBuffer frame, int len);
private native void stopRecord();
public static native int isOpusFile(String path);
public native byte[] getWaveform(String path);
public native byte[] getWaveform2(short[] array, int length);
private class AudioBuffer {
@ -358,7 +365,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
private static final float VOLUME_NORMAL = 1.0f;
private static final int AUDIO_NO_FOCUS_NO_DUCK = 0;
private static final int AUDIO_NO_FOCUS_CAN_DUCK = 1;
private static final int AUDIO_FOCUSED = 2;
private static final int AUDIO_FOCUSED = 2;
private class VideoConvertMessage {
public MessageObject messageObject;
@ -599,7 +606,6 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
}
private class GalleryObserverExternal extends ContentObserver {
public GalleryObserverExternal() {
super(null);
@ -628,7 +634,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
Cursor cursor = null;
try {
if (ApplicationLoader.applicationContext.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
cursor = MediaStore.Images.Media.query(ApplicationLoader.applicationContext.getContentResolver(), MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new String[] {"COUNT(_id)"}, null, null, null);
cursor = MediaStore.Images.Media.query(ApplicationLoader.applicationContext.getContentResolver(), MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new String[]{"COUNT(_id)"}, null, null, null);
if (cursor != null) {
if (cursor.moveToNext()) {
count += cursor.getInt(0);
@ -644,7 +650,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
}
try {
if (ApplicationLoader.applicationContext.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
cursor = MediaStore.Images.Media.query(ApplicationLoader.applicationContext.getContentResolver(), MediaStore.Video.Media.EXTERNAL_CONTENT_URI, new String[] {"COUNT(_id)"}, null, null, null);
cursor = MediaStore.Images.Media.query(ApplicationLoader.applicationContext.getContentResolver(), MediaStore.Video.Media.EXTERNAL_CONTENT_URI, new String[]{"COUNT(_id)"}, null, null, null);
if (cursor != null) {
if (cursor.moveToNext()) {
count += cursor.getInt(0);
@ -2380,7 +2386,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
/*if (Build.VERSION.SDK_INT >= 26) {
ApplicationLoader.applicationContext.startForegroundService(intent);
} else {*/
ApplicationLoader.applicationContext.startService(intent);
ApplicationLoader.applicationContext.startService(intent);
//}
} catch (Throwable e) {
FileLog.e(e);
@ -2731,7 +2737,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
/*if (Build.VERSION.SDK_INT >= 26) {
ApplicationLoader.applicationContext.startForegroundService(intent);
} else {*/
ApplicationLoader.applicationContext.startService(intent);
ApplicationLoader.applicationContext.startService(intent);
//}
} catch (Throwable e) {
FileLog.e(e);
@ -3089,7 +3095,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
}
final File sourceFile = file;
final boolean[] cancelled = new boolean[] {false};
final boolean[] cancelled = new boolean[]{false};
if (sourceFile.exists()) {
AlertDialog progressDialog = null;
if (context != null && type != 0) {
@ -3110,37 +3116,35 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
new Thread(() -> {
try {
File destFile;
File dir;
if (type == 0) {
destFile = AndroidUtilities.generatePicturePath(false, FileLoader.getFileExtension(sourceFile));
dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
} else if (type == 1) {
destFile = AndroidUtilities.generateVideoPath();
dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES);
} else if (type == 2) {
dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
} else {
File dir;
if (type == 2) {
dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
} else {
dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC);
}
dir.mkdir();
destFile = new File(dir, name);
if (destFile.exists()) {
int idx = name.lastIndexOf('.');
for (int a = 0; a < 10; a++) {
String newName;
if (idx != -1) {
newName = name.substring(0, idx) + "(" + (a + 1) + ")" + name.substring(idx);
} else {
newName = name + "(" + (a + 1) + ")";
}
destFile = new File(dir, newName);
if (!destFile.exists()) {
break;
}
dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC);
}
dir = new File(dir,"NekoX");
destFile = new File(dir, name);
if (destFile.exists()) {
int idx = name.lastIndexOf('.');
for (int a = 0; a < 10; a++) {
String newName;
if (idx != -1) {
newName = name.substring(0, idx) + "(" + (a + 1) + ")" + name.substring(idx);
} else {
newName = name + "(" + (a + 1) + ")";
}
destFile = new File(dir, newName);
if (!destFile.exists()) {
break;
}
}
}
if (!destFile.exists()) {
destFile.createNewFile();
FileUtil.initFile(destFile);
}
boolean result = true;
long lastProgress = System.currentTimeMillis() - 500;
@ -3179,7 +3183,11 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
DownloadManager downloadManager = (DownloadManager) ApplicationLoader.applicationContext.getSystemService(Context.DOWNLOAD_SERVICE);
downloadManager.addCompletedDownload(destFile.getName(), destFile.getName(), false, mime, destFile.getAbsolutePath(), destFile.length(), true);
} else {
AndroidUtilities.addMediaToGallery(Uri.fromFile(destFile));
if (Build.VERSION.SDK_INT >= 24) {
AndroidUtilities.addMediaToGallery(FileProvider.getUriForFile(ApplicationLoader.applicationContext, BuildConfig.APPLICATION_ID + ".provider", destFile));
} else {
AndroidUtilities.addMediaToGallery(Uri.fromFile(destFile));
}
}
}
} catch (Exception e) {
@ -3909,6 +3917,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
public interface VideoConvertorListener {
boolean checkConversionCanceled();
void didWriteData(long availableSize,float progress);
void didWriteData(long availableSize, float progress);
}
}

View File

@ -1404,7 +1404,7 @@ public class SharedConfig {
saveProxyList();
setProxyEnable(true);
setProxyEnable(info != null);
}

View File

@ -49,8 +49,7 @@ public class XiaomiUtilities {
Method m = AppOpsManager.class.getMethod("checkOpNoThrow", int.class, int.class, String.class);
int result = (int) m.invoke(mgr, permission, android.os.Process.myUid(), ApplicationLoader.applicationContext.getPackageName());
return result == AppOpsManager.MODE_ALLOWED;
} catch (Exception x) {
FileLog.e(x);
} catch (Exception ignored) {
}
return true;
}

View File

@ -67,6 +67,7 @@ import android.widget.TextView;
import android.widget.Toast;
import org.telegram.PhoneFormat.PhoneFormat;
import org.telegram.messenger.AccountInstance;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.BuildConfig;
@ -125,7 +126,7 @@ import tw.nekomimi.nekogram.NekoXConfig;
import tw.nekomimi.nekogram.utils.AlertUtil;
@SuppressLint("HardwareIds")
public class LoginActivity extends BaseFragment {
public class LoginActivity extends BaseFragment implements NotificationCenter.NotificationCenterDelegate {
private int currentViewNum;
private SlideView[] views = new SlideView[9];
@ -163,6 +164,7 @@ public class LoginActivity extends BaseFragment {
private ActionBarMenuItem proxyItem;
private ProxyDrawable proxyDrawable;
@SuppressWarnings("ConstantConditions")
private boolean useOfficalId = !"release".equals(BuildConfig.BUILD_TYPE);
private class ProgressView extends View {
@ -252,6 +254,15 @@ public class LoginActivity extends BaseFragment {
}
}
@Override
public boolean onFragmentCreate() {
currentConnectionState = getConnectionsManager().getConnectionState();
return true;
}
@Override
public View createView(Context context) {
actionBar.setTitle(LocaleController.getString("NekogramWithEmoji", R.string.NekogramWithEmoji));
@ -371,8 +382,10 @@ public class LoginActivity extends BaseFragment {
ActionBarMenu menu = actionBar.createMenu();
proxyItem = menu.addItem(2, R.drawable.proxy_on);
proxyDrawable = new ProxyDrawable(context);
proxyItem = menu.addItem(2, proxyDrawable);
proxyItem.setContentDescription(LocaleController.getString("ProxySettings", R.string.ProxySettings));
updateProxyButton(false);
menu.addItem(3, R.drawable.ic_translate);
@ -588,6 +601,34 @@ public class LoginActivity extends BaseFragment {
return fragmentView;
}
private int currentConnectionState;
@Override
public void didReceivedNotification(int id, int account, Object... args) {
if (id == NotificationCenter.didUpdateConnectionState) {
int state = AccountInstance.getInstance(account).getConnectionsManager().getConnectionState();
if (currentConnectionState != state) {
currentConnectionState = state;
updateProxyButton(true);
}
}
}
private void updateProxyButton(boolean animated) {
if (proxyDrawable == null || doneItem != null && doneItem.getVisibility() == View.VISIBLE) {
return;
}
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
String proxyAddress = preferences.getString("proxy_ip", "");
boolean proxyEnabled;
if (!actionBar.isSearchFieldVisible() && (doneItem == null || doneItem.getVisibility() != View.VISIBLE)) {
proxyItem.setVisibility(View.VISIBLE);
}
proxyDrawable.setConnected(true, currentConnectionState == ConnectionsManager.ConnectionStateConnected || currentConnectionState == ConnectionsManager.ConnectionStateUpdating, animated);
}
@Override
public void onPause() {
super.onPause();

View File

@ -43,6 +43,7 @@ import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.BuildConfig;
import org.telegram.messenger.DownloadController;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.NotificationCenter;
@ -158,44 +159,47 @@ public class ProxyListActivity extends BaseFragment implements NotificationCente
}
public void updateStatus() {
String colorKey;
if (SharedConfig.currentProxy == currentInfo && useProxySettings) {
if (currentConnectionState == ConnectionsManager.ConnectionStateConnected || currentConnectionState == ConnectionsManager.ConnectionStateUpdating) {
colorKey = Theme.key_windowBackgroundWhiteBlueText6;
if (currentInfo.ping != 0) {
valueTextView.setText(LocaleController.getString("Connected", R.string.Connected) + ", " + LocaleController.formatString("Ping", R.string.Ping, currentInfo.ping));
UIUtil.runOnUIThread(() -> {
String colorKey;
if (SharedConfig.currentProxy == currentInfo && useProxySettings) {
if (currentConnectionState == ConnectionsManager.ConnectionStateConnected || currentConnectionState == ConnectionsManager.ConnectionStateUpdating) {
colorKey = Theme.key_windowBackgroundWhiteBlueText6;
if (currentInfo.ping != 0) {
valueTextView.setText(LocaleController.getString("Connected", R.string.Connected) + ", " + LocaleController.formatString("Ping", R.string.Ping, currentInfo.ping));
} else {
valueTextView.setText(LocaleController.getString("Connected", R.string.Connected));
}
if (!currentInfo.checking && !currentInfo.available) {
currentInfo.availableCheckTime = 0;
}
} else {
valueTextView.setText(LocaleController.getString("Connected", R.string.Connected));
}
if (!currentInfo.checking && !currentInfo.available) {
currentInfo.availableCheckTime = 0;
colorKey = Theme.key_windowBackgroundWhiteGrayText2;
valueTextView.setText(LocaleController.getString("Connecting", R.string.Connecting));
}
} else {
colorKey = Theme.key_windowBackgroundWhiteGrayText2;
valueTextView.setText(LocaleController.getString("Connecting", R.string.Connecting));
}
} else {
if (currentInfo.checking) {
valueTextView.setText(LocaleController.getString("Checking", R.string.Checking));
colorKey = Theme.key_windowBackgroundWhiteGrayText2;
} else if (currentInfo.available) {
if (currentInfo.ping != 0) {
valueTextView.setText(LocaleController.getString("Available", R.string.Available) + ", " + LocaleController.formatString("Ping", R.string.Ping, currentInfo.ping));
if (currentInfo.checking) {
valueTextView.setText(LocaleController.getString("Checking", R.string.Checking));
colorKey = Theme.key_windowBackgroundWhiteGrayText2;
} else if (currentInfo.available) {
if (currentInfo.ping != 0) {
valueTextView.setText(LocaleController.getString("Available", R.string.Available) + ", " + LocaleController.formatString("Ping", R.string.Ping, currentInfo.ping));
} else {
valueTextView.setText(LocaleController.getString("Available", R.string.Available));
}
colorKey = Theme.key_windowBackgroundWhiteGreenText;
} else {
valueTextView.setText(LocaleController.getString("Available", R.string.Available));
valueTextView.setText(LocaleController.getString("Unavailable", R.string.Unavailable));
colorKey = Theme.key_windowBackgroundWhiteRedText4;
}
colorKey = Theme.key_windowBackgroundWhiteGreenText;
} else {
valueTextView.setText(LocaleController.getString("Unavailable", R.string.Unavailable));
colorKey = Theme.key_windowBackgroundWhiteRedText4;
}
}
color = Theme.getColor(colorKey);
valueTextView.setTag(colorKey);
valueTextView.setTextColor(color);
if (checkDrawable != null) {
checkDrawable.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY));
}
color = Theme.getColor(colorKey);
valueTextView.setTag(colorKey);
valueTextView.setTextColor(color);
if (checkDrawable != null) {
checkDrawable.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY));
}
});
}
public void setChecked(boolean checked) {
@ -692,6 +696,12 @@ public class ProxyListActivity extends BaseFragment implements NotificationCente
} else if (position == hidePublicRow) {
if (SharedConfig.proxyEnabled && SharedConfig.currentProxy.isPublic) {
SharedConfig.setCurrentProxy(null);
}
NekoXConfig.toggleHidePublicProxy();
TextCheckCell textCheckCell = (TextCheckCell) view;
@ -1002,9 +1012,12 @@ public class ProxyListActivity extends BaseFragment implements NotificationCente
if (notify && listAdapter != null) {
UIUtil.runOnUIThread(() -> {
try {
listView.clearAnimation();
listView.getRecycledViewPool().clear();
listAdapter.notifyDataSetChanged();
} catch (Exception ignored) {}
} catch (Exception e) {
FileLog.e(e);
}
});
}
}
@ -1041,7 +1054,7 @@ public class ProxyListActivity extends BaseFragment implements NotificationCente
SharedConfig.deleteProxy(proxyInfo);
updateRows(true);
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.proxyCheckDone);
}
@ -1127,13 +1140,17 @@ public class ProxyListActivity extends BaseFragment implements NotificationCente
}
} else if (id == NotificationCenter.proxyCheckDone) {
if (listView != null) {
SharedConfig.ProxyInfo proxyInfo = (SharedConfig.ProxyInfo) args[0];
int idx = SharedConfig.proxyList.indexOf(proxyInfo);
if (idx >= 0) {
RecyclerListView.Holder holder = (RecyclerListView.Holder) listView.findViewHolderForAdapterPosition(idx + proxyStartRow);
if (holder != null && holder.itemView instanceof TextDetailProxyCell) {
TextDetailProxyCell cell = (TextDetailProxyCell) holder.itemView;
cell.updateStatus();
if (args.length == 0) {
updateRows(true);
} else {
SharedConfig.ProxyInfo proxyInfo = (SharedConfig.ProxyInfo) args[0];
int idx = SharedConfig.proxyList.indexOf(proxyInfo);
if (idx >= 0) {
RecyclerListView.Holder holder = (RecyclerListView.Holder) listView.findViewHolderForAdapterPosition(idx + proxyStartRow);
if (holder != null && holder.itemView instanceof TextDetailProxyCell) {
TextDetailProxyCell cell = (TextDetailProxyCell) holder.itemView;
cell.updateStatus();
}
}
}
}

View File

@ -527,7 +527,7 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter
LocaleController.getString("DebugMenuReloadContacts", R.string.DebugMenuReloadContacts),
LocaleController.getString("DebugMenuResetContacts", R.string.DebugMenuResetContacts),
LocaleController.getString("DebugMenuResetDialogs", R.string.DebugMenuResetDialogs),
BuildVars.LOGS_ENABLED ? LocaleController.getString("DebugMenuDisableLogs", R.string.DebugMenuDisableLogs) : LocaleController.getString("DebugMenuEnableLogs", R.string.DebugMenuEnableLogs),
BuildVars.DEBUG_VERSION ? LocaleController.getString("DebugMenuDisableLogs", R.string.DebugMenuDisableLogs) : LocaleController.getString("DebugMenuEnableLogs", R.string.DebugMenuEnableLogs),
NekoConfig.residentNotification ? LocaleController.getString("DisableResidentNotification", R.string.DisableResidentNotification) : LocaleController.getString("EnableResidentNotification", R.string.EnableResidentNotification),
LocaleController.getString("DebugMenuClearMediaCache", R.string.DebugMenuClearMediaCache),
LocaleController.getString("DebugMenuCallSettings", R.string.DebugMenuCallSettings),
@ -880,7 +880,7 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter
helpSectionCell = -1;
debugHeaderRow = -1;
}
if (BuildVars.LOGS_ENABLED) {
if (BuildVars.DEBUG_VERSION) {
sendLogsRow = rowCount++;
clearLogsRow = rowCount++;
} else {

View File

@ -39,9 +39,6 @@ import kotlin.concurrent.thread
class GuardedProcessPool(private val onFatal: suspend (IOException) -> Unit) : CoroutineScope {
companion object {
private const val TAG = "GuardedProcessPool"
private val pid by lazy {
Class.forName("java.lang.ProcessManager\$ProcessImpl").getDeclaredField("pid").apply { isAccessible = true }
}
}
private inner class Guard(private val cmd: List<String>) {
@ -90,18 +87,7 @@ class GuardedProcessPool(private val onFatal: suspend (IOException) -> Unit) : C
FileLog.w("error occurred. stop guard: " + cmd.joinToString(" "))
GlobalScope.launch(Dispatchers.Main) { onFatal(e) }
} finally {
if (running) withContext(NonCancellable) { // clean-up cannot be cancelled
@SuppressLint("NewApi")
if (Build.VERSION.SDK_INT > 21) {
try {
Os.kill(pid.get(process) as Int, OsConstants.SIGTERM)
} catch (e: ErrnoException) {
if (e.errno != OsConstants.ESRCH) FileLog.e(e)
} catch (e: ReflectiveOperationException) {
FileLog.e(e)
}
if (withTimeoutOrNull(500) { exitChannel.receive() } != null) return@withContext
}
if (running) withContext(NonCancellable) {
process.destroy() // kill the process
if (Build.VERSION.SDK_INT >= 26) {
if (withTimeoutOrNull(1000) { exitChannel.receive() } != null) return@withContext

View File

@ -68,26 +68,12 @@ object ProxyManager {
}
private fun mkNewPort(): Int {
val random = Random(System.currentTimeMillis())
var port: Int
do {
port = random.nextInt(2048, 32768)
} while (!isProxyAvailable(port))
return port
}
private fun mkNewPort() = Random.nextInt(2048, 32768)
@JvmStatic
fun isProxyAvailable(port: Int): Boolean {
if (port !in 2048..32767) return false
if (port !in 2048 until 32768) return false
runCatching {

View File

@ -7,24 +7,44 @@ import java.io.File
fun mkDatabase(name: String): Nitrite {
val dir = File("${ApplicationLoader.getDataDirFixed()}/files")
val file = File("${ApplicationLoader.getDataDirFixed()}/files/$name.db")
FileUtil.initDir(dir)
FileUtil.initDir(file.parentFile!!)
runCatching {
return Nitrite.builder().compressed()
.filePath(file.path)
.openOrCreate(name, "nya")!!
}
file.deleteRecursively()
return Nitrite.builder().compressed()
.filePath("$dir/$name.db")
.filePath(file.path)
.openOrCreate(name, "nya")!!
}
fun mkCacheDatabase(name: String) : Nitrite {
fun mkCacheDatabase(name: String): Nitrite {
val dir = File("${ApplicationLoader.getDataDirFixed()}/cache")
val file = File("${ApplicationLoader.getDataDirFixed()}/cache/$name.db")
FileUtil.initDir(dir)
FileUtil.initDir(file.parentFile!!)
runCatching {
return Nitrite.builder().compressed()
.filePath(file.path)
.openOrCreate(name, "nya")!!
}
file.deleteRecursively()
return Nitrite.builder().compressed()
.filePath("$dir/$name.db")
.filePath(file.path)
.openOrCreate(name, "nya")!!
}

View File

@ -342,7 +342,7 @@ object ProxyUtil {
), intArrayOf(
R.drawable.msg_gallery,
R.drawable.cancel_big
R.drawable.msg_cancel
)) { _, i ->