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;
 | 
			
		||||
 | 
			
		||||
import android.annotation.SuppressLint;
 | 
			
		||||
import android.content.ClipData;
 | 
			
		||||
import android.content.ClipboardManager;
 | 
			
		||||
import android.content.ContentResolver;
 | 
			
		||||
@ -32,13 +31,13 @@ import android.database.Cursor;
 | 
			
		||||
import android.net.Uri;
 | 
			
		||||
import android.net.wifi.WifiInfo;
 | 
			
		||||
import android.net.wifi.WifiManager;
 | 
			
		||||
import android.os.AsyncTask;
 | 
			
		||||
import android.os.Build;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.text.Editable;
 | 
			
		||||
import android.text.TextUtils;
 | 
			
		||||
import android.text.TextWatcher;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
import android.util.Pair;
 | 
			
		||||
import android.view.Menu;
 | 
			
		||||
import android.view.MenuInflater;
 | 
			
		||||
import android.view.MenuItem;
 | 
			
		||||
@ -87,6 +86,12 @@ import java.util.Arrays;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
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
 | 
			
		||||
        implements LoaderManager.LoaderCallbacks<Cursor>, RepoAdapter.EnabledListener {
 | 
			
		||||
    private static final String TAG = "ManageReposActivity";
 | 
			
		||||
@ -107,6 +112,8 @@ public class ManageReposActivity extends AppCompatActivity
 | 
			
		||||
     */
 | 
			
		||||
    private boolean finishAfterAddingRepo;
 | 
			
		||||
 | 
			
		||||
    private final CompositeDisposable compositeDisposable = new CompositeDisposable();
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
        FDroidApp fdroidApp = (FDroidApp) getApplication();
 | 
			
		||||
@ -154,6 +161,12 @@ public class ManageReposActivity extends AppCompatActivity
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onDestroy() {
 | 
			
		||||
        compositeDisposable.dispose();
 | 
			
		||||
        super.onDestroy();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean onCreateOptionsMenu(Menu menu) {
 | 
			
		||||
        MenuInflater menuInflater = getMenuInflater();
 | 
			
		||||
@ -571,10 +584,8 @@ public class ManageReposActivity extends AppCompatActivity
 | 
			
		||||
        /**
 | 
			
		||||
         * Adds a new repo to the database.
 | 
			
		||||
         */
 | 
			
		||||
        @SuppressLint("StaticFieldLeak")
 | 
			
		||||
        private void prepareToCreateNewRepo(final String originalAddress, final String fingerprint,
 | 
			
		||||
                                            final String username, final String password) {
 | 
			
		||||
 | 
			
		||||
            final View addRepoForm = addRepoDialog.findViewById(R.id.add_repo_form);
 | 
			
		||||
            addRepoForm.setVisibility(View.GONE);
 | 
			
		||||
            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);
 | 
			
		||||
            skip.setText(R.string.skip);
 | 
			
		||||
 | 
			
		||||
            final AsyncTask<String, String, String> checker = new AsyncTask<String, String, String>() {
 | 
			
		||||
 | 
			
		||||
                private int statusCode = -1;
 | 
			
		||||
                private static final int REFRESH_DIALOG = Integer.MAX_VALUE;
 | 
			
		||||
 | 
			
		||||
                @Override
 | 
			
		||||
                protected String doInBackground(String... params) {
 | 
			
		||||
                    final String originalAddress = params[0];
 | 
			
		||||
            final int REFRESH_DIALOG = Integer.MAX_VALUE;
 | 
			
		||||
            final Disposable disposable = Single.fromCallable(() -> {
 | 
			
		||||
                int statusCode = -1;
 | 
			
		||||
 | 
			
		||||
                if (fingerprintRepoMap.containsKey(fingerprint)) {
 | 
			
		||||
                    statusCode = REFRESH_DIALOG;
 | 
			
		||||
                        return originalAddress;
 | 
			
		||||
                    return Pair.create(statusCode, originalAddress);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (originalAddress.startsWith(ContentResolver.SCHEME_CONTENT)
 | 
			
		||||
                        || originalAddress.startsWith(ContentResolver.SCHEME_FILE)) {
 | 
			
		||||
                    // TODO check whether there is read access
 | 
			
		||||
                        return originalAddress;
 | 
			
		||||
                    return Pair.create(statusCode, originalAddress);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                final String[] pathsToCheck = {"", "fdroid/repo", "repo"};
 | 
			
		||||
                for (final String path : pathsToCheck) {
 | 
			
		||||
 | 
			
		||||
                    Utils.debugLog(TAG, "Check for repo at " + originalAddress + " with suffix '" + path + "'");
 | 
			
		||||
                    Uri.Builder builder = Uri.parse(originalAddress).buildUpon().appendEncodedPath(path);
 | 
			
		||||
                    final String addressWithoutIndex = builder.build().toString();
 | 
			
		||||
                        publishProgress(addressWithoutIndex);
 | 
			
		||||
                    runOnUiThread(() -> textSearching.setText(getString(R.string.repo_searching_address, addressWithoutIndex)));
 | 
			
		||||
 | 
			
		||||
                    if (urlRepoMap.containsKey(addressWithoutIndex)) {
 | 
			
		||||
                        statusCode = REFRESH_DIALOG;
 | 
			
		||||
                            return addressWithoutIndex;
 | 
			
		||||
                        return Pair.create(statusCode, addressWithoutIndex);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    final Uri uri = builder.appendPath(IndexUpdater.SIGNED_FILE_NAME).build();
 | 
			
		||||
 | 
			
		||||
                    try {
 | 
			
		||||
                            if (checkForRepository(uri)) {
 | 
			
		||||
                                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 URL url = new URL(uri.toString());
 | 
			
		||||
                        final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
 | 
			
		||||
                        connection.setRequestMethod("HEAD");
 | 
			
		||||
 | 
			
		||||
                        statusCode = connection.getResponseCode();
 | 
			
		||||
 | 
			
		||||
                    return statusCode == HttpURLConnection.HTTP_UNAUTHORIZED
 | 
			
		||||
                            || statusCode == HttpURLConnection.HTTP_OK;
 | 
			
		||||
                        if (statusCode == HttpURLConnection.HTTP_UNAUTHORIZED || statusCode == HttpURLConnection.HTTP_OK) {
 | 
			
		||||
                            Utils.debugLog(TAG, "Found F-Droid repo at " + addressWithoutIndex);
 | 
			
		||||
                            return Pair.create(statusCode, addressWithoutIndex);
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                @Override
 | 
			
		||||
                protected void onProgressUpdate(String... values) {
 | 
			
		||||
                    String address = values[0];
 | 
			
		||||
                    textSearching.setText(getString(R.string.repo_searching_address, address));
 | 
			
		||||
                    } catch (IOException e) {
 | 
			
		||||
                        Log.e(TAG, "Error while searching for repo at " + addressWithoutIndex, e);
 | 
			
		||||
                        return Pair.create(statusCode, originalAddress);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                @Override
 | 
			
		||||
                protected void onPostExecute(final String newAddress) {
 | 
			
		||||
                }
 | 
			
		||||
                return Pair.create(statusCode, originalAddress);
 | 
			
		||||
            })
 | 
			
		||||
                    .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 (statusCode == HttpURLConnection.HTTP_UNAUTHORIZED) {
 | 
			
		||||
 | 
			
		||||
                                final View view = getLayoutInflater().inflate(R.layout.login, null);
 | 
			
		||||
                                final AlertDialog credentialsDialog = new AlertDialog.Builder(context)
 | 
			
		||||
                                        .setView(view).create();
 | 
			
		||||
@ -679,29 +668,19 @@ public class ManageReposActivity extends AppCompatActivity
 | 
			
		||||
 | 
			
		||||
                                credentialsDialog.setTitle(R.string.login_title);
 | 
			
		||||
                                credentialsDialog.setButton(DialogInterface.BUTTON_NEGATIVE,
 | 
			
		||||
                                    getString(R.string.cancel),
 | 
			
		||||
                                    new DialogInterface.OnClickListener() {
 | 
			
		||||
                                        @Override
 | 
			
		||||
                                        public void onClick(DialogInterface dialog, int which) {
 | 
			
		||||
                                        getString(R.string.cancel), (dialog, which) -> {
 | 
			
		||||
                                            dialog.dismiss();
 | 
			
		||||
                                            // cancel parent dialog, don't add repo
 | 
			
		||||
                                            addRepoDialog.cancel();
 | 
			
		||||
                                        }
 | 
			
		||||
                                        });
 | 
			
		||||
 | 
			
		||||
                                credentialsDialog.setButton(DialogInterface.BUTTON_POSITIVE,
 | 
			
		||||
                                        getString(R.string.ok),
 | 
			
		||||
                                    new DialogInterface.OnClickListener() {
 | 
			
		||||
                                        @Override
 | 
			
		||||
                                        public void onClick(DialogInterface dialog, int which) {
 | 
			
		||||
                                            createNewRepo(newAddress, fingerprint,
 | 
			
		||||
                                        (dialog, which) -> createNewRepo(newAddress, fingerprint,
 | 
			
		||||
                                                nameInput.getText().toString(),
 | 
			
		||||
                                                    passwordInput.getText().toString());
 | 
			
		||||
                                        }
 | 
			
		||||
                                    });
 | 
			
		||||
                                                passwordInput.getText().toString()));
 | 
			
		||||
 | 
			
		||||
                                credentialsDialog.show();
 | 
			
		||||
 | 
			
		||||
                            } else if (statusCode == REFRESH_DIALOG) {
 | 
			
		||||
                                addRepoForm.setVisibility(View.VISIBLE);
 | 
			
		||||
                                positiveButton.setVisibility(View.VISIBLE);
 | 
			
		||||
@ -710,29 +689,22 @@ public class ManageReposActivity extends AppCompatActivity
 | 
			
		||||
                                skip.setOnClickListener(null);
 | 
			
		||||
                                validateRepoDetails(newAddress, fingerprint);
 | 
			
		||||
                            } else {
 | 
			
		||||
 | 
			
		||||
                                // create repo without username/password
 | 
			
		||||
                                createNewRepo(newAddress, fingerprint);
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
                    });
 | 
			
		||||
            compositeDisposable.add(disposable);
 | 
			
		||||
 | 
			
		||||
            skip.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void onClick(View v) {
 | 
			
		||||
            skip.setOnClickListener(v -> {
 | 
			
		||||
                // Still proceed with adding the repo, just don't bother searching for
 | 
			
		||||
                // a better alternative than the one provided.
 | 
			
		||||
                // 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
 | 
			
		||||
                // connection timeouts before being able to proceed.
 | 
			
		||||
 | 
			
		||||
                createNewRepo(originalAddress, fingerprint);
 | 
			
		||||
                    checker.cancel(false);
 | 
			
		||||
                }
 | 
			
		||||
                disposable.dispose();
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            checker.execute(originalAddress);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user