Merge branch 'jmdns-fixes-and-tor-onion-support' into 'master'
Jmdns fixes and tor onion support There are three groups of work in this collection of commits: * improvements to the `WifiStateChangeService` and related activities like JmDNS to eliminate problems that happen when there are a lot of wifi change events. * add rework the `.net.Downloader` stuff to add Tor support and lay the groundwork for Bluetooth support * add support for repos on Tor Hidden Service .onion addresses
This commit is contained in:
		
						commit
						95180512c7
					
				@ -4,7 +4,11 @@
 | 
			
		||||
	<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
 | 
			
		||||
	<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
 | 
			
		||||
	<classpathentry kind="src" path="src"/>
 | 
			
		||||
	<classpathentry kind="src" path="extern/symlinks-for-ant-and-eclipse"/>
 | 
			
		||||
	<classpathentry kind="src" path="extern/symlinks-for-ant-and-eclipse">
 | 
			
		||||
		<attributes>
 | 
			
		||||
			<attribute name="ignore_optional_problems" value="true"/>
 | 
			
		||||
		</attributes>
 | 
			
		||||
	</classpathentry>
 | 
			
		||||
	<classpathentry kind="src" path="gen"/>
 | 
			
		||||
	<classpathentry combineaccessrules="false" kind="src" path="/AndroidPinning"/>
 | 
			
		||||
	<classpathentry combineaccessrules="false" kind="src" path="/MemorizingActivity"/>
 | 
			
		||||
 | 
			
		||||
@ -8,6 +8,8 @@
 | 
			
		||||
 | 
			
		||||
* find local repos on the same network using Bonjour/mDNS
 | 
			
		||||
 | 
			
		||||
* use FDroid repos on Tor Hidden Services (.onion addresses)
 | 
			
		||||
 | 
			
		||||
* directly send installed apps to other devices via Bluetooth and Android Beam
 | 
			
		||||
  (NFC+Bluetooth), also compatible with Samsung/HTC S-Beam
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -41,11 +41,13 @@ import com.nostra13.universalimageloader.utils.StorageUtils;
 | 
			
		||||
 | 
			
		||||
import de.duenndns.ssl.MemorizingTrustManager;
 | 
			
		||||
 | 
			
		||||
import org.fdroid.fdroid.Preferences.ChangeListener;
 | 
			
		||||
import org.fdroid.fdroid.compat.PRNGFixes;
 | 
			
		||||
import org.fdroid.fdroid.data.AppProvider;
 | 
			
		||||
import org.fdroid.fdroid.data.InstalledAppCacheUpdater;
 | 
			
		||||
import org.fdroid.fdroid.data.Repo;
 | 
			
		||||
import org.fdroid.fdroid.localrepo.LocalRepoService;
 | 
			
		||||
import org.fdroid.fdroid.net.IconDownloader;
 | 
			
		||||
import org.fdroid.fdroid.net.WifiStateChangeService;
 | 
			
		||||
import org.thoughtcrime.ssl.pinning.PinningTrustManager;
 | 
			
		||||
import org.thoughtcrime.ssl.pinning.SystemKeyStore;
 | 
			
		||||
@ -151,7 +153,8 @@ public class FDroidApp extends Application {
 | 
			
		||||
        bluetoothAdapter = getBluetoothAdapter();
 | 
			
		||||
 | 
			
		||||
        ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())
 | 
			
		||||
            .discCache(new LimitedAgeDiscCache(
 | 
			
		||||
            .imageDownloader(new IconDownloader(getApplicationContext()))
 | 
			
		||||
            .diskCache(new LimitedAgeDiscCache(
 | 
			
		||||
                        new File(StorageUtils.getCacheDirectory(getApplicationContext(), true),
 | 
			
		||||
                            "icons"),
 | 
			
		||||
                        null,
 | 
			
		||||
@ -213,6 +216,13 @@ public class FDroidApp extends Application {
 | 
			
		||||
        if (wifiState == WifiManager.WIFI_STATE_ENABLING
 | 
			
		||||
                || wifiState == WifiManager.WIFI_STATE_ENABLED)
 | 
			
		||||
            startService(new Intent(this, WifiStateChangeService.class));
 | 
			
		||||
        // if the HTTPS pref changes, then update all affected things
 | 
			
		||||
        Preferences.get().registerLocalRepoHttpsListeners(new ChangeListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onPreferenceChange() {
 | 
			
		||||
                startService(new Intent(FDroidApp.this, WifiStateChangeService.class));
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @TargetApi(18)
 | 
			
		||||
@ -282,17 +292,21 @@ public class FDroidApp extends Application {
 | 
			
		||||
    public static void startLocalRepoService(Context context) {
 | 
			
		||||
        if (!localRepoServiceIsBound) {
 | 
			
		||||
            Context app = context.getApplicationContext();
 | 
			
		||||
            app.bindService(new Intent(app, LocalRepoService.class),
 | 
			
		||||
                    serviceConnection, Context.BIND_AUTO_CREATE);
 | 
			
		||||
            localRepoServiceIsBound = true;
 | 
			
		||||
            Intent service = new Intent(app, LocalRepoService.class);
 | 
			
		||||
            localRepoServiceIsBound = app.bindService(service, serviceConnection,
 | 
			
		||||
                    Context.BIND_AUTO_CREATE);
 | 
			
		||||
            if (localRepoServiceIsBound)
 | 
			
		||||
                app.startService(service);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void stopLocalRepoService(Context context) {
 | 
			
		||||
        Context app = context.getApplicationContext();
 | 
			
		||||
        if (localRepoServiceIsBound) {
 | 
			
		||||
            context.getApplicationContext().unbindService(serviceConnection);
 | 
			
		||||
            app.unbindService(serviceConnection);
 | 
			
		||||
            localRepoServiceIsBound = false;
 | 
			
		||||
        }
 | 
			
		||||
        app.stopService(new Intent(app, LocalRepoService.class));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void restartLocalRepoService() {
 | 
			
		||||
 | 
			
		||||
@ -216,25 +216,31 @@ public class LocalRepoService extends Service {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void registerMDNSService() {
 | 
			
		||||
        String repoName = Preferences.get().getLocalRepoName();
 | 
			
		||||
        final HashMap<String, String> values = new HashMap<String, String>();
 | 
			
		||||
        values.put("path", "/fdroid/repo");
 | 
			
		||||
        values.put("name", repoName);
 | 
			
		||||
        values.put("fingerprint", FDroidApp.repo.fingerprint);
 | 
			
		||||
        String type;
 | 
			
		||||
        if (Preferences.get().isLocalRepoHttpsEnabled()) {
 | 
			
		||||
            values.put("type", "fdroidrepos");
 | 
			
		||||
            type = "_https._tcp.local.";
 | 
			
		||||
        } else {
 | 
			
		||||
            values.put("type", "fdroidrepo");
 | 
			
		||||
            type = "_http._tcp.local.";
 | 
			
		||||
        }
 | 
			
		||||
        pairService = ServiceInfo.create(type, repoName, FDroidApp.port, 0, 0, values);
 | 
			
		||||
        new Thread(new Runnable() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void run() {
 | 
			
		||||
                /*
 | 
			
		||||
                 * a ServiceInfo can only be registered with a single instance
 | 
			
		||||
                 * of JmDNS, and there is only ever a single LocalHTTPD port to
 | 
			
		||||
                 * advertise anyway.
 | 
			
		||||
                 */
 | 
			
		||||
                if (pairService != null || jmdns != null)
 | 
			
		||||
                    clearCurrentMDNSService();
 | 
			
		||||
                String repoName = Preferences.get().getLocalRepoName();
 | 
			
		||||
                HashMap<String, String> values = new HashMap<String, String>();
 | 
			
		||||
                values.put("path", "/fdroid/repo");
 | 
			
		||||
                values.put("name", repoName);
 | 
			
		||||
                values.put("fingerprint", FDroidApp.repo.fingerprint);
 | 
			
		||||
                String type;
 | 
			
		||||
                if (Preferences.get().isLocalRepoHttpsEnabled()) {
 | 
			
		||||
                    values.put("type", "fdroidrepos");
 | 
			
		||||
                    type = "_https._tcp.local.";
 | 
			
		||||
                } else {
 | 
			
		||||
                    values.put("type", "fdroidrepo");
 | 
			
		||||
                    type = "_http._tcp.local.";
 | 
			
		||||
                }
 | 
			
		||||
                try {
 | 
			
		||||
                    pairService = ServiceInfo.create(type, repoName, FDroidApp.port, 0, 0, values);
 | 
			
		||||
                    jmdns = JmDNS.create();
 | 
			
		||||
                    jmdns.registerService(pairService);
 | 
			
		||||
                } catch (IOException e) {
 | 
			
		||||
@ -249,6 +255,10 @@ public class LocalRepoService extends Service {
 | 
			
		||||
            Preferences.get().unregisterLocalRepoBonjourListeners(localRepoBonjourChangeListener);
 | 
			
		||||
            localRepoBonjourChangeListener = null;
 | 
			
		||||
        }
 | 
			
		||||
        clearCurrentMDNSService();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void clearCurrentMDNSService() {
 | 
			
		||||
        if (jmdns != null) {
 | 
			
		||||
            if (pairService != null) {
 | 
			
		||||
                jmdns.unregisterService(pairService);
 | 
			
		||||
 | 
			
		||||
@ -22,6 +22,7 @@ package org.fdroid.fdroid.net;
 | 
			
		||||
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
 | 
			
		||||
import org.fdroid.fdroid.Hasher;
 | 
			
		||||
import org.fdroid.fdroid.ProgressListener;
 | 
			
		||||
import org.fdroid.fdroid.data.Apk;
 | 
			
		||||
@ -172,8 +173,7 @@ public class ApkDownloader implements AsyncDownloadWrapper.Listener {
 | 
			
		||||
        Log.d(TAG, "Downloading apk from " + remoteAddress);
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
 | 
			
		||||
            Downloader downloader = new HttpDownloader(remoteAddress, localFile);
 | 
			
		||||
            Downloader downloader = DownloaderFactory.create(remoteAddress, localFile);
 | 
			
		||||
            dlWrapper = new AsyncDownloadWrapper(downloader, this);
 | 
			
		||||
            dlWrapper.download();
 | 
			
		||||
            return true;
 | 
			
		||||
 | 
			
		||||
@ -14,6 +14,7 @@ import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.io.OutputStream;
 | 
			
		||||
import java.net.MalformedURLException;
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
 | 
			
		||||
public abstract class Downloader {
 | 
			
		||||
 | 
			
		||||
@ -23,31 +24,32 @@ public abstract class Downloader {
 | 
			
		||||
    private ProgressListener progressListener = null;
 | 
			
		||||
    private Bundle eventData = null;
 | 
			
		||||
    private File outputFile;
 | 
			
		||||
 | 
			
		||||
    protected URL sourceUrl;
 | 
			
		||||
    protected String cacheTag = null;
 | 
			
		||||
 | 
			
		||||
    public static final String EVENT_PROGRESS = "downloadProgress";
 | 
			
		||||
 | 
			
		||||
    public abstract InputStream inputStream() throws IOException;
 | 
			
		||||
    public abstract InputStream getInputStream() throws IOException;
 | 
			
		||||
 | 
			
		||||
    // The context is required for opening the file to write to.
 | 
			
		||||
    public Downloader(String destFile, Context ctx)
 | 
			
		||||
    Downloader(String destFile, Context ctx)
 | 
			
		||||
            throws FileNotFoundException, MalformedURLException {
 | 
			
		||||
        this(new File(ctx.getFilesDir() + File.separator + destFile));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // The context is required for opening the file to write to.
 | 
			
		||||
    public Downloader(Context ctx) throws IOException {
 | 
			
		||||
    Downloader(Context ctx) throws IOException {
 | 
			
		||||
        this(File.createTempFile("dl-", "", ctx.getCacheDir()));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Downloader(File destFile)
 | 
			
		||||
    Downloader(File destFile)
 | 
			
		||||
            throws FileNotFoundException, MalformedURLException {
 | 
			
		||||
        // http://developer.android.com/guide/topics/data/data-storage.html#InternalCache
 | 
			
		||||
        outputFile = destFile;
 | 
			
		||||
        outputStream = new FileOutputStream(outputFile);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Downloader(OutputStream output)
 | 
			
		||||
    Downloader(OutputStream output)
 | 
			
		||||
            throws MalformedURLException {
 | 
			
		||||
        outputStream = output;
 | 
			
		||||
        outputFile   = null;
 | 
			
		||||
@ -118,13 +120,13 @@ public abstract class Downloader {
 | 
			
		||||
        Log.d(TAG, "Downloading from stream");
 | 
			
		||||
        InputStream input = null;
 | 
			
		||||
        try {
 | 
			
		||||
            input = inputStream();
 | 
			
		||||
            input = getInputStream();
 | 
			
		||||
 | 
			
		||||
            // Getting the input stream is slow(ish) for HTTP downloads, so we'll check if
 | 
			
		||||
            // we were interrupted before proceeding to the download.
 | 
			
		||||
            throwExceptionIfInterrupted();
 | 
			
		||||
 | 
			
		||||
            copyInputToOutputStream(inputStream());
 | 
			
		||||
            copyInputToOutputStream(getInputStream());
 | 
			
		||||
        } finally {
 | 
			
		||||
            Utils.closeQuietly(outputStream);
 | 
			
		||||
            Utils.closeQuietly(input);
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										32
									
								
								src/org/fdroid/fdroid/net/DownloaderFactory.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								src/org/fdroid/fdroid/net/DownloaderFactory.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,32 @@
 | 
			
		||||
 | 
			
		||||
package org.fdroid.fdroid.net;
 | 
			
		||||
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
 | 
			
		||||
public class DownloaderFactory {
 | 
			
		||||
 | 
			
		||||
    public static Downloader create(String url, Context context)
 | 
			
		||||
            throws IOException {
 | 
			
		||||
        if (isOnionAddress(url)) {
 | 
			
		||||
            return new TorHttpDownloader(url, context);
 | 
			
		||||
        } else {
 | 
			
		||||
            return new HttpDownloader(url, context);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static Downloader create(String url, File destFile)
 | 
			
		||||
            throws IOException {
 | 
			
		||||
        if (isOnionAddress(url)) {
 | 
			
		||||
            return new TorHttpDownloader(url, destFile);
 | 
			
		||||
        } else {
 | 
			
		||||
            return new HttpDownloader(url, destFile);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static boolean isOnionAddress(String url) {
 | 
			
		||||
        return url.matches("^[a-zA-Z0-9]+://[^/]+\\.onion/.*");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -7,33 +7,23 @@ import java.io.File;
 | 
			
		||||
import java.io.FileNotFoundException;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.io.OutputStream;
 | 
			
		||||
import java.net.HttpURLConnection;
 | 
			
		||||
import java.net.MalformedURLException;
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
import java.net.UnknownHostException;
 | 
			
		||||
 | 
			
		||||
import javax.net.ssl.SSLHandshakeException;
 | 
			
		||||
 | 
			
		||||
public class HttpDownloader extends Downloader {
 | 
			
		||||
    private static final String TAG = "org.fdroid.fdroid.net.HttpDownloader";
 | 
			
		||||
 | 
			
		||||
    private static final String HEADER_IF_NONE_MATCH = "If-None-Match";
 | 
			
		||||
    private static final String HEADER_FIELD_ETAG = "ETag";
 | 
			
		||||
    protected static final String HEADER_IF_NONE_MATCH = "If-None-Match";
 | 
			
		||||
    protected static final String HEADER_FIELD_ETAG = "ETag";
 | 
			
		||||
 | 
			
		||||
    private URL sourceUrl;
 | 
			
		||||
    private HttpURLConnection connection;
 | 
			
		||||
    protected HttpURLConnection connection;
 | 
			
		||||
    private int statusCode = -1;
 | 
			
		||||
 | 
			
		||||
    // The context is required for opening the file to write to.
 | 
			
		||||
    public HttpDownloader(String source, String destFile, Context ctx)
 | 
			
		||||
            throws FileNotFoundException, MalformedURLException {
 | 
			
		||||
        super(destFile, ctx);
 | 
			
		||||
        sourceUrl = new URL(source);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // The context is required for opening the file to write to.
 | 
			
		||||
    public HttpDownloader(String source, File destFile)
 | 
			
		||||
    HttpDownloader(String source, File destFile)
 | 
			
		||||
            throws FileNotFoundException, MalformedURLException {
 | 
			
		||||
        super(destFile);
 | 
			
		||||
        sourceUrl = new URL(source);
 | 
			
		||||
@ -42,20 +32,17 @@ public class HttpDownloader extends Downloader {
 | 
			
		||||
    /**
 | 
			
		||||
     * Downloads to a temporary file, which *you must delete yourself when
 | 
			
		||||
     * you are done*.
 | 
			
		||||
     * @see org.fdroid.fdroid.net.HttpDownloader#getFile()
 | 
			
		||||
     * @see org.fdroid.fdroid.net.Downloader#getFile()
 | 
			
		||||
     */
 | 
			
		||||
    public HttpDownloader(String source, Context ctx) throws IOException {
 | 
			
		||||
    HttpDownloader(String source, Context ctx) throws IOException {
 | 
			
		||||
        super(ctx);
 | 
			
		||||
        sourceUrl = new URL(source);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public HttpDownloader(String source, OutputStream output)
 | 
			
		||||
            throws MalformedURLException {
 | 
			
		||||
        super(output);
 | 
			
		||||
        sourceUrl = new URL(source);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public InputStream inputStream() throws IOException {
 | 
			
		||||
    @Override
 | 
			
		||||
    public InputStream getInputStream() throws IOException {
 | 
			
		||||
        setupConnection();
 | 
			
		||||
        // TODO check out BaseImageDownloader.getStreamFromNetwork() for optims
 | 
			
		||||
        return connection.getInputStream();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -68,31 +55,41 @@ public class HttpDownloader extends Downloader {
 | 
			
		||||
    @Override
 | 
			
		||||
    public void download() throws IOException, InterruptedException {
 | 
			
		||||
        try {
 | 
			
		||||
            connection = (HttpURLConnection)sourceUrl.openConnection();
 | 
			
		||||
 | 
			
		||||
            if (wantToCheckCache()) {
 | 
			
		||||
                setupCacheCheck();
 | 
			
		||||
                Log.i(TAG, "Checking cached status of " + sourceUrl);
 | 
			
		||||
                statusCode = connection.getResponseCode();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (isCached()) {
 | 
			
		||||
                Log.i(TAG, sourceUrl + " is cached, so not downloading (HTTP " + statusCode + ")");
 | 
			
		||||
            } else {
 | 
			
		||||
                Log.i(TAG, "Downloading from " + sourceUrl);
 | 
			
		||||
                downloadFromStream();
 | 
			
		||||
                updateCacheCheck();
 | 
			
		||||
            }
 | 
			
		||||
            setupConnection();
 | 
			
		||||
            doDownload();
 | 
			
		||||
        } catch (SSLHandshakeException e) {
 | 
			
		||||
            // TODO this should be handled better, it is not internationalised here.
 | 
			
		||||
            // TODO this should be handled better, it is not internationalised here
 | 
			
		||||
            throw new IOException(
 | 
			
		||||
                    "A problem occurred while establishing an SSL " +
 | 
			
		||||
                            "connection. If this problem persists, AND you have a " +
 | 
			
		||||
                            "very old device, you could try using http instead of " +
 | 
			
		||||
                            "https for the repo URL." + Log.getStackTraceString(e) );
 | 
			
		||||
                            "https for the repo URL." + Log.getStackTraceString(e));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected void setupConnection() throws IOException {
 | 
			
		||||
        if (connection != null)
 | 
			
		||||
            return;
 | 
			
		||||
        connection = (HttpURLConnection) sourceUrl.openConnection();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected void doDownload() throws IOException, InterruptedException {
 | 
			
		||||
        if (wantToCheckCache()) {
 | 
			
		||||
            setupCacheCheck();
 | 
			
		||||
            Log.i(TAG, "Checking cached status of " + sourceUrl);
 | 
			
		||||
            statusCode = connection.getResponseCode();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (isCached()) {
 | 
			
		||||
            Log.i(TAG, sourceUrl + " is cached, so not downloading (HTTP " + statusCode + ")");
 | 
			
		||||
        } else {
 | 
			
		||||
            Log.i(TAG, "Downloading from " + sourceUrl);
 | 
			
		||||
            downloadFromStream();
 | 
			
		||||
            updateCacheCheck();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean isCached() {
 | 
			
		||||
        return wantToCheckCache() && statusCode == 304;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										32
									
								
								src/org/fdroid/fdroid/net/IconDownloader.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								src/org/fdroid/fdroid/net/IconDownloader.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,32 @@
 | 
			
		||||
 | 
			
		||||
package org.fdroid.fdroid.net;
 | 
			
		||||
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
 | 
			
		||||
import com.nostra13.universalimageloader.core.download.BaseImageDownloader;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
 | 
			
		||||
public class IconDownloader extends BaseImageDownloader {
 | 
			
		||||
 | 
			
		||||
    public IconDownloader(Context context) {
 | 
			
		||||
        super(context);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public IconDownloader(Context context, int connectTimeout, int readTimeout) {
 | 
			
		||||
        super(context, connectTimeout, readTimeout);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public InputStream getStream(String imageUri, Object extra) throws IOException {
 | 
			
		||||
        switch (Scheme.ofUri(imageUri)) {
 | 
			
		||||
            case HTTP:
 | 
			
		||||
            case HTTPS:
 | 
			
		||||
                Downloader downloader = DownloaderFactory.create(imageUri, context);
 | 
			
		||||
                return downloader.getInputStream();
 | 
			
		||||
            default:
 | 
			
		||||
                return super.getStream(imageUri, extra);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										32
									
								
								src/org/fdroid/fdroid/net/TorHttpDownloader.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								src/org/fdroid/fdroid/net/TorHttpDownloader.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,32 @@
 | 
			
		||||
 | 
			
		||||
package org.fdroid.fdroid.net;
 | 
			
		||||
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.FileNotFoundException;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.net.HttpURLConnection;
 | 
			
		||||
import java.net.InetSocketAddress;
 | 
			
		||||
import java.net.MalformedURLException;
 | 
			
		||||
import java.net.Proxy;
 | 
			
		||||
import java.net.SocketAddress;
 | 
			
		||||
 | 
			
		||||
public class TorHttpDownloader extends HttpDownloader {
 | 
			
		||||
 | 
			
		||||
    TorHttpDownloader(String url, Context ctx) throws IOException {
 | 
			
		||||
        super(url, ctx);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    TorHttpDownloader(String url, File destFile)
 | 
			
		||||
            throws FileNotFoundException, MalformedURLException {
 | 
			
		||||
        super(url, destFile);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void setupConnection() throws IOException {
 | 
			
		||||
            SocketAddress sa = new InetSocketAddress("127.0.0.1", 8118);
 | 
			
		||||
            Proxy tor = new Proxy(Proxy.Type.HTTP, sa);
 | 
			
		||||
            connection = (HttpURLConnection) sourceUrl.openConnection(tor);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -23,9 +23,14 @@ import java.util.Locale;
 | 
			
		||||
public class WifiStateChangeService extends Service {
 | 
			
		||||
    public static final String BROADCAST = "org.fdroid.fdroid.action.WIFI_CHANGE";
 | 
			
		||||
 | 
			
		||||
    private static WaitForWifiAsyncTask asyncTask;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int onStartCommand(Intent intent, int flags, int startId) {
 | 
			
		||||
        new WaitForWifiAsyncTask().execute();
 | 
			
		||||
        if (asyncTask != null)
 | 
			
		||||
            asyncTask.cancel(true);
 | 
			
		||||
        asyncTask = new WaitForWifiAsyncTask();
 | 
			
		||||
        asyncTask.execute();
 | 
			
		||||
        return START_NOT_STICKY;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -38,15 +43,21 @@ public class WifiStateChangeService extends Service {
 | 
			
		||||
            wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
 | 
			
		||||
            try {
 | 
			
		||||
                while (!wifiManager.isWifiEnabled()) {
 | 
			
		||||
                    if (isCancelled())
 | 
			
		||||
                        return null;
 | 
			
		||||
                    Log.i(TAG, "waiting for the wifi to be enabled...");
 | 
			
		||||
                    Thread.sleep(3000);
 | 
			
		||||
                    Thread.sleep(1000);
 | 
			
		||||
                }
 | 
			
		||||
                int ipAddress = wifiManager.getConnectionInfo().getIpAddress();
 | 
			
		||||
                while (ipAddress == 0) {
 | 
			
		||||
                    if (isCancelled())
 | 
			
		||||
                        return null;
 | 
			
		||||
                    Log.i(TAG, "waiting for an IP address...");
 | 
			
		||||
                    Thread.sleep(3000);
 | 
			
		||||
                    Thread.sleep(1000);
 | 
			
		||||
                    ipAddress = wifiManager.getConnectionInfo().getIpAddress();
 | 
			
		||||
                }
 | 
			
		||||
                if (isCancelled())
 | 
			
		||||
                    return null;
 | 
			
		||||
                WifiInfo wifiInfo = wifiManager.getConnectionInfo();
 | 
			
		||||
                ipAddress = wifiInfo.getIpAddress();
 | 
			
		||||
                FDroidApp.ipAddressString = String.format(Locale.ENGLISH, "%d.%d.%d.%d",
 | 
			
		||||
@ -67,6 +78,9 @@ public class WifiStateChangeService extends Service {
 | 
			
		||||
                FDroidApp.repo.address = String.format(Locale.ENGLISH, "%s://%s:%d/fdroid/repo",
 | 
			
		||||
                        scheme, FDroidApp.ipAddressString, FDroidApp.port);
 | 
			
		||||
 | 
			
		||||
                if (isCancelled())
 | 
			
		||||
                    return null;
 | 
			
		||||
 | 
			
		||||
                Context context = WifiStateChangeService.this.getApplicationContext();
 | 
			
		||||
                LocalRepoKeyStore localRepoKeyStore = LocalRepoKeyStore.get(context);
 | 
			
		||||
                Certificate localCert = localRepoKeyStore.getCertificate();
 | 
			
		||||
@ -75,6 +89,9 @@ public class WifiStateChangeService extends Service {
 | 
			
		||||
                lrm.setUriString(FDroidApp.repo.address);
 | 
			
		||||
                lrm.writeIndexPage(Utils.getSharingUri(context, FDroidApp.repo).toString());
 | 
			
		||||
 | 
			
		||||
                if (isCancelled())
 | 
			
		||||
                    return null;
 | 
			
		||||
 | 
			
		||||
                /*
 | 
			
		||||
                 * Once the IP address is known we need to generate a self
 | 
			
		||||
                 * signed certificate to use for HTTPS that has a CN field set
 | 
			
		||||
 | 
			
		||||
@ -13,7 +13,7 @@ import org.fdroid.fdroid.data.App;
 | 
			
		||||
import org.fdroid.fdroid.data.Repo;
 | 
			
		||||
import org.fdroid.fdroid.data.RepoProvider;
 | 
			
		||||
import org.fdroid.fdroid.net.Downloader;
 | 
			
		||||
import org.fdroid.fdroid.net.HttpDownloader;
 | 
			
		||||
import org.fdroid.fdroid.net.DownloaderFactory;
 | 
			
		||||
import org.xml.sax.InputSource;
 | 
			
		||||
import org.xml.sax.SAXException;
 | 
			
		||||
import org.xml.sax.XMLReader;
 | 
			
		||||
@ -89,7 +89,7 @@ abstract public class RepoUpdater {
 | 
			
		||||
    protected Downloader downloadIndex() throws UpdateException {
 | 
			
		||||
        Downloader downloader = null;
 | 
			
		||||
        try {
 | 
			
		||||
            downloader = new HttpDownloader(getIndexAddress(), context);
 | 
			
		||||
            downloader = DownloaderFactory.create(getIndexAddress(), context);
 | 
			
		||||
            downloader.setCacheTag(repo.lastetag);
 | 
			
		||||
 | 
			
		||||
            if (progressListener != null) { // interactive session, show progress
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user