Merge branch 'index-downloads-from-mirrors' into 'master'
Index downloads from mirrors See merge request fdroid/fdroidclient!730
This commit is contained in:
commit
9cfe8ef091
@ -25,7 +25,7 @@ import android.support.v7.app.AppCompatActivity;
|
|||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
import org.fdroid.fdroid.R;
|
import org.fdroid.fdroid.R;
|
||||||
import org.fdroid.fdroid.views.fragments.PreferencesFragment;
|
import org.fdroid.fdroid.views.PreferencesFragment;
|
||||||
import org.fdroid.fdroid.views.updates.UpdatesViewBinder;
|
import org.fdroid.fdroid.views.updates.UpdatesViewBinder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -10,7 +10,7 @@ import android.widget.Button;
|
|||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import org.fdroid.fdroid.R;
|
import org.fdroid.fdroid.R;
|
||||||
import org.fdroid.fdroid.views.fragments.PreferencesFragment;
|
import org.fdroid.fdroid.views.PreferencesFragment;
|
||||||
import org.fdroid.fdroid.views.swap.SwapWorkflowActivity;
|
import org.fdroid.fdroid.views.swap.SwapWorkflowActivity;
|
||||||
import org.fdroid.fdroid.views.updates.UpdatesViewBinder;
|
import org.fdroid.fdroid.views.updates.UpdatesViewBinder;
|
||||||
|
|
||||||
|
@ -47,11 +47,19 @@ import org.fdroid.fdroid.data.Schema;
|
|||||||
import org.fdroid.fdroid.net.Downloader;
|
import org.fdroid.fdroid.net.Downloader;
|
||||||
import org.fdroid.fdroid.net.DownloaderFactory;
|
import org.fdroid.fdroid.net.DownloaderFactory;
|
||||||
|
|
||||||
|
import javax.net.ssl.SSLHandshakeException;
|
||||||
|
import javax.net.ssl.SSLKeyException;
|
||||||
|
import javax.net.ssl.SSLPeerUnverifiedException;
|
||||||
|
import javax.net.ssl.SSLProtocolException;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.ConnectException;
|
import java.net.ConnectException;
|
||||||
|
import java.net.HttpRetryException;
|
||||||
|
import java.net.NoRouteToHostException;
|
||||||
|
import java.net.ProtocolException;
|
||||||
import java.net.SocketTimeoutException;
|
import java.net.SocketTimeoutException;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
@ -94,6 +102,7 @@ public class IndexV1Updater extends RepoUpdater {
|
|||||||
/**
|
/**
|
||||||
* @return whether this successfully found an index of this version
|
* @return whether this successfully found an index of this version
|
||||||
* @throws RepoUpdater.UpdateException
|
* @throws RepoUpdater.UpdateException
|
||||||
|
* @see org.fdroid.fdroid.net.DownloaderService#handleIntent(android.content.Intent)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean update() throws RepoUpdater.UpdateException {
|
public boolean update() throws RepoUpdater.UpdateException {
|
||||||
@ -119,7 +128,10 @@ public class IndexV1Updater extends RepoUpdater {
|
|||||||
}
|
}
|
||||||
|
|
||||||
processDownloadedIndex(downloader.outputFile, downloader.getCacheTag());
|
processDownloadedIndex(downloader.outputFile, downloader.getCacheTag());
|
||||||
} catch (ConnectException | SocketTimeoutException e) {
|
} catch (ConnectException | HttpRetryException | NoRouteToHostException | SocketTimeoutException
|
||||||
|
| SSLHandshakeException | SSLKeyException | SSLPeerUnverifiedException | SSLProtocolException
|
||||||
|
| ProtocolException | UnknownHostException e) {
|
||||||
|
// if the above list changes, also change below and in DownloaderService.handleIntent()
|
||||||
Utils.debugLog(TAG, "Trying to download the index from a mirror");
|
Utils.debugLog(TAG, "Trying to download the index from a mirror");
|
||||||
// Mirror logic here, so that the default download code is untouched.
|
// Mirror logic here, so that the default download code is untouched.
|
||||||
String mirrorUrl;
|
String mirrorUrl;
|
||||||
@ -146,7 +158,9 @@ public class IndexV1Updater extends RepoUpdater {
|
|||||||
|
|
||||||
processDownloadedIndex(downloader.outputFile, downloader.getCacheTag());
|
processDownloadedIndex(downloader.outputFile, downloader.getCacheTag());
|
||||||
break;
|
break;
|
||||||
} catch (ConnectException | SocketTimeoutException e2) {
|
} catch (ConnectException | HttpRetryException | NoRouteToHostException | SocketTimeoutException
|
||||||
|
| SSLHandshakeException | SSLKeyException | SSLPeerUnverifiedException | SSLProtocolException
|
||||||
|
| ProtocolException | UnknownHostException e2) {
|
||||||
// We'll just let this try the next mirror
|
// We'll just let this try the next mirror
|
||||||
Utils.debugLog(TAG, "Trying next mirror");
|
Utils.debugLog(TAG, "Trying next mirror");
|
||||||
} catch (IOException e2) {
|
} catch (IOException e2) {
|
||||||
|
@ -193,7 +193,7 @@ public final class Preferences implements SharedPreferences.OnSharedPreferenceCh
|
|||||||
* of the Privileged Extension. The preference provides a way to disable using the
|
* of the Privileged Extension. The preference provides a way to disable using the
|
||||||
* Privileged Extension even though its installed.
|
* Privileged Extension even though its installed.
|
||||||
*
|
*
|
||||||
* @see org.fdroid.fdroid.views.fragments.PreferencesFragment#initPrivilegedInstallerPreference()
|
* @see org.fdroid.fdroid.views.PreferencesFragment#initPrivilegedInstallerPreference()
|
||||||
*/
|
*/
|
||||||
public boolean isPrivilegedInstallerEnabled() {
|
public boolean isPrivilegedInstallerEnabled() {
|
||||||
return preferences.getBoolean(PREF_PRIVILEGED_INSTALLER, true);
|
return preferences.getBoolean(PREF_PRIVILEGED_INSTALLER, true);
|
||||||
|
@ -22,7 +22,6 @@ package org.fdroid.fdroid;
|
|||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
import org.fdroid.fdroid.data.Apk;
|
import org.fdroid.fdroid.data.Apk;
|
||||||
import org.fdroid.fdroid.data.App;
|
import org.fdroid.fdroid.data.App;
|
||||||
import org.fdroid.fdroid.data.Repo;
|
import org.fdroid.fdroid.data.Repo;
|
||||||
@ -129,11 +128,11 @@ public class RepoXMLHandler extends DefaultHandler {
|
|||||||
if (currentApkHashType == null || "md5".equals(currentApkHashType)) {
|
if (currentApkHashType == null || "md5".equals(currentApkHashType)) {
|
||||||
if (curapk.hash == null) {
|
if (curapk.hash == null) {
|
||||||
curapk.hash = str;
|
curapk.hash = str;
|
||||||
curapk.hashType = "SHA-256";
|
curapk.hashType = "sha256";
|
||||||
}
|
}
|
||||||
} else if ("sha256".equals(currentApkHashType)) {
|
} else if ("sha256".equals(currentApkHashType)) {
|
||||||
curapk.hash = str;
|
curapk.hash = str;
|
||||||
curapk.hashType = "SHA-256";
|
curapk.hashType = "sha256";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ApkTable.Cols.SIGNATURE:
|
case ApkTable.Cols.SIGNATURE:
|
||||||
|
@ -362,7 +362,7 @@ public final class Utils {
|
|||||||
String ret = null;
|
String ret = null;
|
||||||
try {
|
try {
|
||||||
// keytool -list -v gives you the SHA-256 fingerprint
|
// keytool -list -v gives you the SHA-256 fingerprint
|
||||||
MessageDigest digest = MessageDigest.getInstance("SHA-256");
|
MessageDigest digest = MessageDigest.getInstance("sha256");
|
||||||
digest.update(key);
|
digest.update(key);
|
||||||
byte[] fingerprint = digest.digest();
|
byte[] fingerprint = digest.digest();
|
||||||
Formatter formatter = new Formatter(new StringBuilder());
|
Formatter formatter = new Formatter(new StringBuilder());
|
||||||
|
@ -280,7 +280,6 @@ public class DBHelper extends SQLiteOpenHelper {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
||||||
super.onDowngrade(db, oldVersion, newVersion);
|
|
||||||
resetTransient(context);
|
resetTransient(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,7 +240,7 @@ public class InstallManagerService extends Service {
|
|||||||
* @see <a href="https://developer.android.com/google/play/expansion-files.html">APK Expansion Files</a>
|
* @see <a href="https://developer.android.com/google/play/expansion-files.html">APK Expansion Files</a>
|
||||||
*/
|
*/
|
||||||
private void getObb(final String urlString, String obbUrlString,
|
private void getObb(final String urlString, String obbUrlString,
|
||||||
final File obbDestFile, final String sha256) {
|
final File obbDestFile, final String hash) {
|
||||||
if (obbDestFile == null || obbDestFile.exists() || TextUtils.isEmpty(obbUrlString)) {
|
if (obbDestFile == null || obbDestFile.exists() || TextUtils.isEmpty(obbUrlString)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -267,7 +267,7 @@ public class InstallManagerService extends Service {
|
|||||||
+ " to " + localApkUri);
|
+ " to " + localApkUri);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (Hasher.isFileMatchingHash(localFile, sha256, "SHA-256")) {
|
if (Hasher.isFileMatchingHash(localFile, hash, "sha256")) {
|
||||||
Utils.debugLog(TAG, "Installing OBB " + localFile + " to " + obbDestFile);
|
Utils.debugLog(TAG, "Installing OBB " + localFile + " to " + obbDestFile);
|
||||||
FileUtils.forceMkdirParent(obbDestFile);
|
FileUtils.forceMkdirParent(obbDestFile);
|
||||||
FileUtils.copyFile(localFile, obbDestFile);
|
FileUtils.copyFile(localFile, obbDestFile);
|
||||||
@ -280,7 +280,7 @@ public class InstallManagerService extends Service {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Utils.debugLog(TAG, localFile + " deleted, did not match hash: " + sha256);
|
Utils.debugLog(TAG, localFile + " deleted, did not match hash: " + hash);
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
@ -47,6 +47,7 @@ import java.io.IOException;
|
|||||||
import java.net.ConnectException;
|
import java.net.ConnectException;
|
||||||
import java.net.HttpRetryException;
|
import java.net.HttpRetryException;
|
||||||
import java.net.NoRouteToHostException;
|
import java.net.NoRouteToHostException;
|
||||||
|
import java.net.ProtocolException;
|
||||||
import java.net.SocketTimeoutException;
|
import java.net.SocketTimeoutException;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
|
|
||||||
@ -193,6 +194,7 @@ public class DownloaderService extends Service {
|
|||||||
*
|
*
|
||||||
* @param intent The {@link Intent} passed via {@link
|
* @param intent The {@link Intent} passed via {@link
|
||||||
* android.content.Context#startService(Intent)}.
|
* android.content.Context#startService(Intent)}.
|
||||||
|
* @see org.fdroid.fdroid.IndexV1Updater#update()
|
||||||
*/
|
*/
|
||||||
private void handleIntent(Intent intent) {
|
private void handleIntent(Intent intent) {
|
||||||
final Uri uri = intent.getData();
|
final Uri uri = intent.getData();
|
||||||
@ -225,7 +227,8 @@ public class DownloaderService extends Service {
|
|||||||
sendBroadcast(uri, Downloader.ACTION_INTERRUPTED, localFile, repoId, originalUrlString);
|
sendBroadcast(uri, Downloader.ACTION_INTERRUPTED, localFile, repoId, originalUrlString);
|
||||||
} catch (ConnectException | HttpRetryException | NoRouteToHostException | SocketTimeoutException
|
} catch (ConnectException | HttpRetryException | NoRouteToHostException | SocketTimeoutException
|
||||||
| SSLHandshakeException | SSLKeyException | SSLPeerUnverifiedException | SSLProtocolException
|
| SSLHandshakeException | SSLKeyException | SSLPeerUnverifiedException | SSLProtocolException
|
||||||
| UnknownHostException e) {
|
| ProtocolException | UnknownHostException e) {
|
||||||
|
// if the above list of exceptions changes, also change it in IndexV1Updater.update()
|
||||||
Log.e(TAG, e.getLocalizedMessage());
|
Log.e(TAG, e.getLocalizedMessage());
|
||||||
sendBroadcast(uri, Downloader.ACTION_CONNECTION_FAILED, localFile, repoId, originalUrlString);
|
sendBroadcast(uri, Downloader.ACTION_CONNECTION_FAILED, localFile, repoId, originalUrlString);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@ -271,29 +274,31 @@ public class DownloaderService extends Service {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a URL to the download queue.
|
* Add a URL to the download queue.
|
||||||
* <p/>
|
* <p>
|
||||||
* All notifications are sent as an {@link Intent} via local broadcasts to be received by
|
* All notifications are sent as an {@link Intent} via local broadcasts to be received by
|
||||||
*
|
*
|
||||||
* @param context this app's {@link Context}
|
* @param context this app's {@link Context}
|
||||||
* @param urlString The URL to add to the download queue
|
* @param mirrorUrlString The URL to add to the download queue
|
||||||
|
* @param repoId the database ID number representing one repo
|
||||||
|
* @param urlString the URL used as the unique ID throughout F-Droid
|
||||||
* @see #cancel(Context, String)
|
* @see #cancel(Context, String)
|
||||||
*/
|
*/
|
||||||
public static void queue(Context context, String urlString, long repoId, String originalUrlString) {
|
public static void queue(Context context, String mirrorUrlString, long repoId, String urlString) {
|
||||||
if (TextUtils.isEmpty(urlString)) {
|
if (TextUtils.isEmpty(mirrorUrlString)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Utils.debugLog(TAG, "Preparing " + urlString + " to go into the download queue");
|
Utils.debugLog(TAG, "Preparing " + mirrorUrlString + " to go into the download queue");
|
||||||
Intent intent = new Intent(context, DownloaderService.class);
|
Intent intent = new Intent(context, DownloaderService.class);
|
||||||
intent.setAction(ACTION_QUEUE);
|
intent.setAction(ACTION_QUEUE);
|
||||||
intent.setData(Uri.parse(urlString));
|
intent.setData(Uri.parse(mirrorUrlString));
|
||||||
intent.putExtra(Downloader.EXTRA_REPO_ID, repoId);
|
intent.putExtra(Downloader.EXTRA_REPO_ID, repoId);
|
||||||
intent.putExtra(Downloader.EXTRA_CANONICAL_URL, originalUrlString);
|
intent.putExtra(Downloader.EXTRA_CANONICAL_URL, urlString);
|
||||||
context.startService(intent);
|
context.startService(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a URL to the download queue, even if it is currently downloading.
|
* Remove a URL to the download queue, even if it is currently downloading.
|
||||||
* <p/>
|
* <p>
|
||||||
* All notifications are sent as an {@link Intent} via local broadcasts to be received by
|
* All notifications are sent as an {@link Intent} via local broadcasts to be received by
|
||||||
*
|
*
|
||||||
* @param context this app's {@link Context}
|
* @param context this app's {@link Context}
|
||||||
|
@ -37,7 +37,6 @@ import java.io.File;
|
|||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.ConnectException;
|
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.SocketTimeoutException;
|
import java.net.SocketTimeoutException;
|
||||||
@ -106,7 +105,7 @@ public class HttpDownloader extends Downloader {
|
|||||||
* @see <a href="http://lucb1e.com/rp/cookielesscookies">Cookieless cookies</a>
|
* @see <a href="http://lucb1e.com/rp/cookielesscookies">Cookieless cookies</a>
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void download() throws ConnectException, IOException, InterruptedException {
|
public void download() throws IOException, InterruptedException {
|
||||||
// get the file size from the server
|
// get the file size from the server
|
||||||
HttpURLConnection tmpConn = getConnection();
|
HttpURLConnection tmpConn = getConnection();
|
||||||
tmpConn.setRequestMethod("HEAD");
|
tmpConn.setRequestMethod("HEAD");
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
* MA 02110-1301, USA.
|
* MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.fdroid.fdroid.views.fragments;
|
package org.fdroid.fdroid.views;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
@ -55,7 +55,6 @@ import org.fdroid.fdroid.Utils;
|
|||||||
import org.fdroid.fdroid.data.RepoProvider;
|
import org.fdroid.fdroid.data.RepoProvider;
|
||||||
import org.fdroid.fdroid.installer.InstallHistoryService;
|
import org.fdroid.fdroid.installer.InstallHistoryService;
|
||||||
import org.fdroid.fdroid.installer.PrivilegedInstaller;
|
import org.fdroid.fdroid.installer.PrivilegedInstaller;
|
||||||
import org.fdroid.fdroid.views.LiveSeekBarPreference;
|
|
||||||
|
|
||||||
public class PreferencesFragment extends PreferenceFragment
|
public class PreferencesFragment extends PreferenceFragment
|
||||||
implements SharedPreferences.OnSharedPreferenceChangeListener {
|
implements SharedPreferences.OnSharedPreferenceChangeListener {
|
@ -8,7 +8,7 @@ import android.support.v7.app.AppCompatActivity;
|
|||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
import org.fdroid.fdroid.R;
|
import org.fdroid.fdroid.R;
|
||||||
import org.fdroid.fdroid.views.fragments.PreferencesFragment;
|
import org.fdroid.fdroid.views.PreferencesFragment;
|
||||||
|
|
||||||
@SuppressWarnings("LineLength")
|
@SuppressWarnings("LineLength")
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user