Create new repos using RxJava instead of AsyncTask.
This commit is contained in:
parent
e1ca1552f7
commit
242662d02a
@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
package org.fdroid.fdroid.views;
|
package org.fdroid.fdroid.views;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
|
||||||
import android.content.ClipData;
|
import android.content.ClipData;
|
||||||
import android.content.ClipboardManager;
|
import android.content.ClipboardManager;
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
@ -32,13 +31,13 @@ import android.database.Cursor;
|
|||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.net.wifi.WifiInfo;
|
import android.net.wifi.WifiInfo;
|
||||||
import android.net.wifi.WifiManager;
|
import android.net.wifi.WifiManager;
|
||||||
import android.os.AsyncTask;
|
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.text.TextWatcher;
|
import android.text.TextWatcher;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.util.Pair;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
@ -87,6 +86,12 @@ import java.util.Arrays;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
|
||||||
|
import io.reactivex.rxjava3.core.Single;
|
||||||
|
import io.reactivex.rxjava3.disposables.CompositeDisposable;
|
||||||
|
import io.reactivex.rxjava3.disposables.Disposable;
|
||||||
|
import io.reactivex.rxjava3.schedulers.Schedulers;
|
||||||
|
|
||||||
public class ManageReposActivity extends AppCompatActivity
|
public class ManageReposActivity extends AppCompatActivity
|
||||||
implements LoaderManager.LoaderCallbacks<Cursor>, RepoAdapter.EnabledListener {
|
implements LoaderManager.LoaderCallbacks<Cursor>, RepoAdapter.EnabledListener {
|
||||||
private static final String TAG = "ManageReposActivity";
|
private static final String TAG = "ManageReposActivity";
|
||||||
@ -107,6 +112,8 @@ public class ManageReposActivity extends AppCompatActivity
|
|||||||
*/
|
*/
|
||||||
private boolean finishAfterAddingRepo;
|
private boolean finishAfterAddingRepo;
|
||||||
|
|
||||||
|
private final CompositeDisposable compositeDisposable = new CompositeDisposable();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
FDroidApp fdroidApp = (FDroidApp) getApplication();
|
FDroidApp fdroidApp = (FDroidApp) getApplication();
|
||||||
@ -154,6 +161,12 @@ public class ManageReposActivity extends AppCompatActivity
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
compositeDisposable.dispose();
|
||||||
|
super.onDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
MenuInflater menuInflater = getMenuInflater();
|
MenuInflater menuInflater = getMenuInflater();
|
||||||
@ -571,10 +584,8 @@ public class ManageReposActivity extends AppCompatActivity
|
|||||||
/**
|
/**
|
||||||
* Adds a new repo to the database.
|
* Adds a new repo to the database.
|
||||||
*/
|
*/
|
||||||
@SuppressLint("StaticFieldLeak")
|
|
||||||
private void prepareToCreateNewRepo(final String originalAddress, final String fingerprint,
|
private void prepareToCreateNewRepo(final String originalAddress, final String fingerprint,
|
||||||
final String username, final String password) {
|
final String username, final String password) {
|
||||||
|
|
||||||
final View addRepoForm = addRepoDialog.findViewById(R.id.add_repo_form);
|
final View addRepoForm = addRepoDialog.findViewById(R.id.add_repo_form);
|
||||||
addRepoForm.setVisibility(View.GONE);
|
addRepoForm.setVisibility(View.GONE);
|
||||||
final View positiveButton = addRepoDialog.getButton(AlertDialog.BUTTON_POSITIVE);
|
final View positiveButton = addRepoDialog.getButton(AlertDialog.BUTTON_POSITIVE);
|
||||||
@ -586,84 +597,62 @@ public class ManageReposActivity extends AppCompatActivity
|
|||||||
final Button skip = addRepoDialog.getButton(AlertDialog.BUTTON_NEGATIVE);
|
final Button skip = addRepoDialog.getButton(AlertDialog.BUTTON_NEGATIVE);
|
||||||
skip.setText(R.string.skip);
|
skip.setText(R.string.skip);
|
||||||
|
|
||||||
final AsyncTask<String, String, String> checker = new AsyncTask<String, String, String>() {
|
final int REFRESH_DIALOG = Integer.MAX_VALUE;
|
||||||
|
final Disposable disposable = Single.fromCallable(() -> {
|
||||||
private int statusCode = -1;
|
int statusCode = -1;
|
||||||
private static final int REFRESH_DIALOG = Integer.MAX_VALUE;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String doInBackground(String... params) {
|
|
||||||
final String originalAddress = params[0];
|
|
||||||
|
|
||||||
if (fingerprintRepoMap.containsKey(fingerprint)) {
|
if (fingerprintRepoMap.containsKey(fingerprint)) {
|
||||||
statusCode = REFRESH_DIALOG;
|
statusCode = REFRESH_DIALOG;
|
||||||
return originalAddress;
|
return Pair.create(statusCode, originalAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (originalAddress.startsWith(ContentResolver.SCHEME_CONTENT)
|
if (originalAddress.startsWith(ContentResolver.SCHEME_CONTENT)
|
||||||
|| originalAddress.startsWith(ContentResolver.SCHEME_FILE)) {
|
|| originalAddress.startsWith(ContentResolver.SCHEME_FILE)) {
|
||||||
// TODO check whether there is read access
|
// TODO check whether there is read access
|
||||||
return originalAddress;
|
return Pair.create(statusCode, originalAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
final String[] pathsToCheck = {"", "fdroid/repo", "repo"};
|
final String[] pathsToCheck = {"", "fdroid/repo", "repo"};
|
||||||
for (final String path : pathsToCheck) {
|
for (final String path : pathsToCheck) {
|
||||||
|
|
||||||
Utils.debugLog(TAG, "Check for repo at " + originalAddress + " with suffix '" + path + "'");
|
Utils.debugLog(TAG, "Check for repo at " + originalAddress + " with suffix '" + path + "'");
|
||||||
Uri.Builder builder = Uri.parse(originalAddress).buildUpon().appendEncodedPath(path);
|
Uri.Builder builder = Uri.parse(originalAddress).buildUpon().appendEncodedPath(path);
|
||||||
final String addressWithoutIndex = builder.build().toString();
|
final String addressWithoutIndex = builder.build().toString();
|
||||||
publishProgress(addressWithoutIndex);
|
runOnUiThread(() -> textSearching.setText(getString(R.string.repo_searching_address, addressWithoutIndex)));
|
||||||
|
|
||||||
if (urlRepoMap.containsKey(addressWithoutIndex)) {
|
if (urlRepoMap.containsKey(addressWithoutIndex)) {
|
||||||
statusCode = REFRESH_DIALOG;
|
statusCode = REFRESH_DIALOG;
|
||||||
return addressWithoutIndex;
|
return Pair.create(statusCode, addressWithoutIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
final Uri uri = builder.appendPath(IndexUpdater.SIGNED_FILE_NAME).build();
|
final Uri uri = builder.appendPath(IndexUpdater.SIGNED_FILE_NAME).build();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (checkForRepository(uri)) {
|
final URL url = new URL(uri.toString());
|
||||||
Utils.debugLog(TAG, "Found F-Droid repo at " + addressWithoutIndex);
|
|
||||||
return addressWithoutIndex;
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.e(TAG, "Error while searching for repo at " + addressWithoutIndex, e);
|
|
||||||
return originalAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isCancelled()) {
|
|
||||||
Utils.debugLog(TAG, "Not checking more repo addresses, because process was skipped.");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return originalAddress;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean checkForRepository(Uri indexUri) throws IOException {
|
|
||||||
final URL url = new URL(indexUri.toString());
|
|
||||||
final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||||
connection.setRequestMethod("HEAD");
|
connection.setRequestMethod("HEAD");
|
||||||
|
|
||||||
statusCode = connection.getResponseCode();
|
statusCode = connection.getResponseCode();
|
||||||
|
|
||||||
return statusCode == HttpURLConnection.HTTP_UNAUTHORIZED
|
if (statusCode == HttpURLConnection.HTTP_UNAUTHORIZED || statusCode == HttpURLConnection.HTTP_OK) {
|
||||||
|| statusCode == HttpURLConnection.HTTP_OK;
|
Utils.debugLog(TAG, "Found F-Droid repo at " + addressWithoutIndex);
|
||||||
|
return Pair.create(statusCode, addressWithoutIndex);
|
||||||
}
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
@Override
|
Log.e(TAG, "Error while searching for repo at " + addressWithoutIndex, e);
|
||||||
protected void onProgressUpdate(String... values) {
|
return Pair.create(statusCode, originalAddress);
|
||||||
String address = values[0];
|
|
||||||
textSearching.setText(getString(R.string.repo_searching_address, address));
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
@Override
|
return Pair.create(statusCode, originalAddress);
|
||||||
protected void onPostExecute(final String newAddress) {
|
})
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.doOnDispose(() -> Utils.debugLog(TAG, "Not checking more repo addresses, because process was skipped."))
|
||||||
|
.subscribe(codeAddressPair -> {
|
||||||
|
final int statusCode = codeAddressPair.first;
|
||||||
|
final String newAddress = codeAddressPair.second;
|
||||||
|
|
||||||
if (addRepoDialog.isShowing()) {
|
if (addRepoDialog.isShowing()) {
|
||||||
|
|
||||||
if (statusCode == HttpURLConnection.HTTP_UNAUTHORIZED) {
|
if (statusCode == HttpURLConnection.HTTP_UNAUTHORIZED) {
|
||||||
|
|
||||||
final View view = getLayoutInflater().inflate(R.layout.login, null);
|
final View view = getLayoutInflater().inflate(R.layout.login, null);
|
||||||
final AlertDialog credentialsDialog = new AlertDialog.Builder(context)
|
final AlertDialog credentialsDialog = new AlertDialog.Builder(context)
|
||||||
.setView(view).create();
|
.setView(view).create();
|
||||||
@ -679,29 +668,19 @@ public class ManageReposActivity extends AppCompatActivity
|
|||||||
|
|
||||||
credentialsDialog.setTitle(R.string.login_title);
|
credentialsDialog.setTitle(R.string.login_title);
|
||||||
credentialsDialog.setButton(DialogInterface.BUTTON_NEGATIVE,
|
credentialsDialog.setButton(DialogInterface.BUTTON_NEGATIVE,
|
||||||
getString(R.string.cancel),
|
getString(R.string.cancel), (dialog, which) -> {
|
||||||
new DialogInterface.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
|
||||||
dialog.dismiss();
|
dialog.dismiss();
|
||||||
// cancel parent dialog, don't add repo
|
// cancel parent dialog, don't add repo
|
||||||
addRepoDialog.cancel();
|
addRepoDialog.cancel();
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
credentialsDialog.setButton(DialogInterface.BUTTON_POSITIVE,
|
credentialsDialog.setButton(DialogInterface.BUTTON_POSITIVE,
|
||||||
getString(R.string.ok),
|
getString(R.string.ok),
|
||||||
new DialogInterface.OnClickListener() {
|
(dialog, which) -> createNewRepo(newAddress, fingerprint,
|
||||||
@Override
|
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
|
||||||
createNewRepo(newAddress, fingerprint,
|
|
||||||
nameInput.getText().toString(),
|
nameInput.getText().toString(),
|
||||||
passwordInput.getText().toString());
|
passwordInput.getText().toString()));
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
credentialsDialog.show();
|
credentialsDialog.show();
|
||||||
|
|
||||||
} else if (statusCode == REFRESH_DIALOG) {
|
} else if (statusCode == REFRESH_DIALOG) {
|
||||||
addRepoForm.setVisibility(View.VISIBLE);
|
addRepoForm.setVisibility(View.VISIBLE);
|
||||||
positiveButton.setVisibility(View.VISIBLE);
|
positiveButton.setVisibility(View.VISIBLE);
|
||||||
@ -710,29 +689,22 @@ public class ManageReposActivity extends AppCompatActivity
|
|||||||
skip.setOnClickListener(null);
|
skip.setOnClickListener(null);
|
||||||
validateRepoDetails(newAddress, fingerprint);
|
validateRepoDetails(newAddress, fingerprint);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// create repo without username/password
|
// create repo without username/password
|
||||||
createNewRepo(newAddress, fingerprint);
|
createNewRepo(newAddress, fingerprint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
};
|
compositeDisposable.add(disposable);
|
||||||
|
|
||||||
skip.setOnClickListener(new View.OnClickListener() {
|
skip.setOnClickListener(v -> {
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
// Still proceed with adding the repo, just don't bother searching for
|
// Still proceed with adding the repo, just don't bother searching for
|
||||||
// a better alternative than the one provided.
|
// a better alternative than the one provided.
|
||||||
// The reason for this is that if they are not connected to the internet,
|
// The reason for this is that if they are not connected to the internet,
|
||||||
// or their internet is playing up, then you'd have to wait for several
|
// or their internet is playing up, then you'd have to wait for several
|
||||||
// connection timeouts before being able to proceed.
|
// connection timeouts before being able to proceed.
|
||||||
|
|
||||||
createNewRepo(originalAddress, fingerprint);
|
createNewRepo(originalAddress, fingerprint);
|
||||||
checker.cancel(false);
|
disposable.dispose();
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
checker.execute(originalAddress);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user