Merge branch 'bluetooth-swap' of https://gitlab.com/n8fr8/fdroidclient
This commit is contained in:
commit
2159b3d49b
@ -98,7 +98,9 @@ public class RepoUpdater {
|
|||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
if (downloader != null && downloader.getFile() != null) {
|
if (downloader != null && downloader.getFile() != null) {
|
||||||
downloader.getFile().delete();
|
downloader.getFile().delete();
|
||||||
|
downloader.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new UpdateException(repo, "Error getting index file from " + repo.address, e);
|
throw new UpdateException(repo, "Error getting index file from " + repo.address, e);
|
||||||
}
|
}
|
||||||
return downloader;
|
return downloader;
|
||||||
@ -121,6 +123,8 @@ public class RepoUpdater {
|
|||||||
// successful download, then we will have a file ready to use:
|
// successful download, then we will have a file ready to use:
|
||||||
processDownloadedFile(downloader.getFile(), downloader.getCacheTag());
|
processDownloadedFile(downloader.getFile(), downloader.getCacheTag());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
downloader.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void processDownloadedFile(File downloadedFile, String cacheTag) throws UpdateException {
|
protected void processDownloadedFile(File downloadedFile, String cacheTag) throws UpdateException {
|
||||||
@ -278,7 +282,7 @@ public class RepoUpdater {
|
|||||||
* actually in the index.jar itself. If no fingerprint, just store the
|
* actually in the index.jar itself. If no fingerprint, just store the
|
||||||
* signing certificate */
|
* signing certificate */
|
||||||
boolean trustNewSigningCertificate = false;
|
boolean trustNewSigningCertificate = false;
|
||||||
if (repo.fingerprint == null) {
|
if (repo.fingerprint == null || TextUtils.isEmpty(repo.fingerprint)) {
|
||||||
// no info to check things are valid, so just Trust On First Use
|
// no info to check things are valid, so just Trust On First Use
|
||||||
trustNewSigningCertificate = true;
|
trustNewSigningCertificate = true;
|
||||||
} else {
|
} else {
|
||||||
|
@ -241,7 +241,7 @@ public class App extends ValueObject implements Comparable<App> {
|
|||||||
PackageManager.GET_META_DATA);
|
PackageManager.GET_META_DATA);
|
||||||
installerPackageLabel = installerAppInfo.loadLabel(pm);
|
installerPackageLabel = installerAppInfo.loadLabel(pm);
|
||||||
} catch (PackageManager.NameNotFoundException e) {
|
} catch (PackageManager.NameNotFoundException e) {
|
||||||
Log.w(TAG, "Could not get app info", e);
|
Log.w(TAG, "Could not get app info: " + installerPackageName,e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (TextUtils.isEmpty(installerPackageLabel))
|
if (TextUtils.isEmpty(installerPackageLabel))
|
||||||
|
@ -486,8 +486,12 @@ public class LocalRepoManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void writeIndexJar() throws IOException {
|
public void writeIndexJar() throws IOException {
|
||||||
|
|
||||||
|
FileWriter writer;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
new IndexXmlBuilder(context, apps).build(xmlIndex);
|
writer = new FileWriter(xmlIndex);
|
||||||
|
new IndexXmlBuilder(context, apps).build(writer);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e(TAG, "Could not write index jar", e);
|
Log.e(TAG, "Could not write index jar", e);
|
||||||
Toast.makeText(context, R.string.failed_to_create_index, Toast.LENGTH_LONG).show();
|
Toast.makeText(context, R.string.failed_to_create_index, Toast.LENGTH_LONG).show();
|
||||||
@ -512,6 +516,7 @@ public class LocalRepoManager {
|
|||||||
bi.close();
|
bi.close();
|
||||||
jo.close();
|
jo.close();
|
||||||
bo.close();
|
bo.close();
|
||||||
|
writer.close();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
LocalRepoKeyStore.get(context).signZip(xmlIndexJarUnsigned, xmlIndexJar);
|
LocalRepoKeyStore.get(context).signZip(xmlIndexJarUnsigned, xmlIndexJar);
|
||||||
|
@ -108,13 +108,17 @@ public class SwapService extends Service {
|
|||||||
|
|
||||||
public void scanForPeers() {
|
public void scanForPeers() {
|
||||||
Log.d(TAG, "Scanning for nearby devices to swap with...");
|
Log.d(TAG, "Scanning for nearby devices to swap with...");
|
||||||
|
|
||||||
bonjourFinder.scan();
|
bonjourFinder.scan();
|
||||||
bluetoothFinder.scan();
|
bluetoothFinder.scan();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stopScanningForPeers() {
|
public void stopScanningForPeers() {
|
||||||
|
|
||||||
bonjourFinder.cancel();
|
bonjourFinder.cancel();
|
||||||
bluetoothFinder.cancel();
|
bluetoothFinder.cancel();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -452,7 +456,7 @@ public class SwapService extends Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isBluetoothDiscoverable() {
|
public boolean isBluetoothDiscoverable() {
|
||||||
return bluetoothSwap.isConnected();
|
return bluetoothSwap.isDiscoverable();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isBonjourDiscoverable() {
|
public boolean isBonjourDiscoverable() {
|
||||||
@ -530,10 +534,11 @@ public class SwapService extends Service {
|
|||||||
filter.addAction(WIFI_STATE_CHANGE);
|
filter.addAction(WIFI_STATE_CHANGE);
|
||||||
LocalBroadcastManager.getInstance(this).registerReceiver(receiveSwapStatusChanged, filter);
|
LocalBroadcastManager.getInstance(this).registerReceiver(receiveSwapStatusChanged, filter);
|
||||||
|
|
||||||
|
/**
|
||||||
if (wasBluetoothEnabled()) {
|
if (wasBluetoothEnabled()) {
|
||||||
Log.d(TAG, "Previously the user enabled Bluetooth swap, so enabling again automatically.");
|
Log.d(TAG, "Previously the user enabled Bluetooth swap, so enabling again automatically.");
|
||||||
bluetoothSwap.startInBackground();
|
bluetoothSwap.startInBackground();
|
||||||
}
|
}*/
|
||||||
|
|
||||||
if (wasWifiEnabled()) {
|
if (wasWifiEnabled()) {
|
||||||
Log.d(TAG, "Previously the user enabled Wifi swap, so enabling again automatically.");
|
Log.d(TAG, "Previously the user enabled Wifi swap, so enabling again automatically.");
|
||||||
@ -574,7 +579,7 @@ public class SwapService extends Service {
|
|||||||
|
|
||||||
public void disableAllSwapping() {
|
public void disableAllSwapping() {
|
||||||
Log.i(TAG, "Asked to stop swapping, will stop bluetooth, wifi, and move service to BG for GC.");
|
Log.i(TAG, "Asked to stop swapping, will stop bluetooth, wifi, and move service to BG for GC.");
|
||||||
getBluetoothSwap().stopInBackground();
|
// getBluetoothSwap().stopInBackground();
|
||||||
getWifiSwap().stopInBackground();
|
getWifiSwap().stopInBackground();
|
||||||
|
|
||||||
// Ensure the user is sent back go the first screen when returning if we have just forceably
|
// Ensure the user is sent back go the first screen when returning if we have just forceably
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package org.fdroid.fdroid.localrepo.peers;
|
package org.fdroid.fdroid.localrepo.peers;
|
||||||
|
|
||||||
import android.bluetooth.BluetoothAdapter;
|
import android.bluetooth.BluetoothAdapter;
|
||||||
|
import android.bluetooth.BluetoothClass;
|
||||||
import android.bluetooth.BluetoothDevice;
|
import android.bluetooth.BluetoothDevice;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@ -14,6 +15,8 @@ public class BluetoothFinder extends PeerFinder<BluetoothPeer> {
|
|||||||
|
|
||||||
private static final String TAG = "BluetoothFinder";
|
private static final String TAG = "BluetoothFinder";
|
||||||
|
|
||||||
|
public final static int DISCOVERABLE_TIMEOUT = 3600;
|
||||||
|
|
||||||
private final BluetoothAdapter adapter;
|
private final BluetoothAdapter adapter;
|
||||||
|
|
||||||
public BluetoothFinder(Context context) {
|
public BluetoothFinder(Context context) {
|
||||||
@ -92,9 +95,17 @@ public class BluetoothFinder extends PeerFinder<BluetoothPeer> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void onDeviceFound(BluetoothDevice device) {
|
private void onDeviceFound(BluetoothDevice device) {
|
||||||
if (device != null && device.getName() != null && device.getName().startsWith(BluetoothSwap.BLUETOOTH_NAME_TAG)) {
|
|
||||||
|
if(device != null && device.getName() != null &&
|
||||||
|
(device.getBluetoothClass().getDeviceClass() == BluetoothClass.Device.COMPUTER_HANDHELD_PC_PDA||
|
||||||
|
device.getBluetoothClass().getDeviceClass() == BluetoothClass.Device.COMPUTER_PALM_SIZE_PC_PDA||
|
||||||
|
device.getBluetoothClass().getDeviceClass() == BluetoothClass.Device.PHONE_SMART))
|
||||||
|
{
|
||||||
foundPeer(new BluetoothPeer(device));
|
foundPeer(new BluetoothPeer(device));
|
||||||
}
|
}
|
||||||
|
// if (device != null && device.getName() != null && device.getName().startsWith(BluetoothSwap.BLUETOOTH_NAME_TAG)) {
|
||||||
|
// foundPeer(new BluetoothPeer(device));
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import android.content.BroadcastReceiver;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
|
import android.os.AsyncTask;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@ -17,8 +18,12 @@ public class BluetoothSwap extends SwapType {
|
|||||||
private static final String TAG = "BluetoothBroadcastType";
|
private static final String TAG = "BluetoothBroadcastType";
|
||||||
public final static String BLUETOOTH_NAME_TAG = "FDroid:";
|
public final static String BLUETOOTH_NAME_TAG = "FDroid:";
|
||||||
|
|
||||||
|
private static BluetoothSwap mInstance = null;
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
private final BluetoothAdapter adapter;
|
private final BluetoothAdapter adapter;
|
||||||
|
private BroadcastReceiver receiver;
|
||||||
|
private boolean isDiscoverable = false;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private BluetoothServer server;
|
private BluetoothServer server;
|
||||||
@ -30,7 +35,10 @@ public class BluetoothSwap extends SwapType {
|
|||||||
if (adapter == null) {
|
if (adapter == null) {
|
||||||
return new NoBluetoothType(context);
|
return new NoBluetoothType(context);
|
||||||
} else {
|
} else {
|
||||||
return new BluetoothSwap(context, adapter);
|
if (mInstance == null)
|
||||||
|
mInstance = new BluetoothSwap(context, adapter);
|
||||||
|
|
||||||
|
return mInstance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,24 +46,12 @@ public class BluetoothSwap extends SwapType {
|
|||||||
super(context);
|
super(context);
|
||||||
this.adapter = adapter;
|
this.adapter = adapter;
|
||||||
|
|
||||||
context.registerReceiver(new BroadcastReceiver() {
|
|
||||||
@Override
|
|
||||||
public void onReceive(Context context, Intent intent) {
|
|
||||||
switch (intent.getIntExtra(BluetoothAdapter.EXTRA_SCAN_MODE, -1)) {
|
|
||||||
case BluetoothAdapter.SCAN_MODE_NONE:
|
|
||||||
setConnected(false);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE:
|
}
|
||||||
if (server != null && server.isRunning()) {
|
|
||||||
setConnected(true);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Only other is BluetoothAdapter.SCAN_MODE_CONNECTABLE. For now don't handle that.
|
@Override
|
||||||
}
|
public boolean isDiscoverable () {
|
||||||
}
|
return isDiscoverable;
|
||||||
}, new IntentFilter(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -64,20 +60,48 @@ public class BluetoothSwap extends SwapType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start() {
|
public synchronized void start() {
|
||||||
|
|
||||||
|
if (isConnected())
|
||||||
|
return;
|
||||||
|
|
||||||
|
receiver = new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
switch (intent.getIntExtra(BluetoothAdapter.EXTRA_SCAN_MODE, -1)) {
|
||||||
|
case BluetoothAdapter.SCAN_MODE_NONE:
|
||||||
|
setConnected(false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE:
|
||||||
|
isDiscoverable = true;
|
||||||
|
if (server != null && server.isRunning()) {
|
||||||
|
setConnected(true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Only other is BluetoothAdapter.SCAN_MODE_CONNECTABLE. For now don't handle that.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
context.registerReceiver(receiver, new IntentFilter(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED));
|
||||||
|
|
||||||
|
/*
|
||||||
if (server != null) {
|
if (server != null) {
|
||||||
Log.d(TAG, "Attempting to start Bluetooth swap, but it appears to be running already. Will cancel it so it can be restarted.");
|
Log.d(TAG, "Attempting to start Bluetooth swap, but it appears to be running already. Will cancel it so it can be restarted.");
|
||||||
server.close();
|
server.close();
|
||||||
server = null;
|
server = null;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
server = new BluetoothServer(this, context.getFilesDir());
|
if (server == null)
|
||||||
|
server = new BluetoothServer(this, context.getFilesDir());
|
||||||
|
|
||||||
sendBroadcast(SwapService.EXTRA_STARTING);
|
sendBroadcast(SwapService.EXTRA_STARTING);
|
||||||
|
|
||||||
//store the original bluetoothname, and update this one to be unique
|
//store the original bluetoothname, and update this one to be unique
|
||||||
deviceBluetoothName = adapter.getName();
|
deviceBluetoothName = adapter.getName();
|
||||||
|
|
||||||
|
/*
|
||||||
Log.d(TAG, "Prefixing Bluetooth adapter name with " + BLUETOOTH_NAME_TAG + " to make it identifiable as a swap device.");
|
Log.d(TAG, "Prefixing Bluetooth adapter name with " + BLUETOOTH_NAME_TAG + " to make it identifiable as a swap device.");
|
||||||
if (!deviceBluetoothName.startsWith(BLUETOOTH_NAME_TAG))
|
if (!deviceBluetoothName.startsWith(BLUETOOTH_NAME_TAG))
|
||||||
adapter.setName(BLUETOOTH_NAME_TAG + deviceBluetoothName);
|
adapter.setName(BLUETOOTH_NAME_TAG + deviceBluetoothName);
|
||||||
@ -85,7 +109,7 @@ public class BluetoothSwap extends SwapType {
|
|||||||
if (!adapter.getName().startsWith(BLUETOOTH_NAME_TAG)) {
|
if (!adapter.getName().startsWith(BLUETOOTH_NAME_TAG)) {
|
||||||
Log.e(TAG, "Couldn't change the name of the Bluetooth adapter, it will not get recognized by other swap clients.");
|
Log.e(TAG, "Couldn't change the name of the Bluetooth adapter, it will not get recognized by other swap clients.");
|
||||||
// TODO: Should we bail here?
|
// TODO: Should we bail here?
|
||||||
}
|
}*/
|
||||||
|
|
||||||
if (!adapter.isEnabled()) {
|
if (!adapter.isEnabled()) {
|
||||||
Log.d(TAG, "Bluetooth adapter is disabled, attempting to enable.");
|
Log.d(TAG, "Bluetooth adapter is disabled, attempting to enable.");
|
||||||
@ -96,8 +120,8 @@ public class BluetoothSwap extends SwapType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (adapter.isEnabled()) {
|
if (adapter.isEnabled())
|
||||||
server.start();
|
{
|
||||||
setConnected(true);
|
setConnected(true);
|
||||||
} else {
|
} else {
|
||||||
Log.i(TAG, "Didn't start Bluetooth swapping server, because Bluetooth is disabled and couldn't be enabled.");
|
Log.i(TAG, "Didn't start Bluetooth swapping server, because Bluetooth is disabled and couldn't be enabled.");
|
||||||
@ -110,6 +134,11 @@ public class BluetoothSwap extends SwapType {
|
|||||||
if (server != null && server.isAlive()) {
|
if (server != null && server.isAlive()) {
|
||||||
server.close();
|
server.close();
|
||||||
setConnected(false);
|
setConnected(false);
|
||||||
|
|
||||||
|
// if (receiver != null) {
|
||||||
|
// context.unregisterReceiver(receiver);
|
||||||
|
// receiver = null;
|
||||||
|
// }
|
||||||
} else {
|
} else {
|
||||||
Log.i(TAG, "Attempting to stop Bluetooth swap, but it is not currently running.");
|
Log.i(TAG, "Attempting to stop Bluetooth swap, but it is not currently running.");
|
||||||
}
|
}
|
||||||
@ -141,5 +170,6 @@ public class BluetoothSwap extends SwapType {
|
|||||||
protected String getBroadcastAction() {
|
protected String getBroadcastAction() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,11 @@ public abstract class SwapType {
|
|||||||
|
|
||||||
abstract protected String getBroadcastAction();
|
abstract protected String getBroadcastAction();
|
||||||
|
|
||||||
|
public boolean isDiscoverable ()
|
||||||
|
{
|
||||||
|
return isConnected();
|
||||||
|
}
|
||||||
|
|
||||||
protected final void setConnected(boolean connected) {
|
protected final void setConnected(boolean connected) {
|
||||||
if (connected) {
|
if (connected) {
|
||||||
isConnected = true;
|
isConnected = true;
|
||||||
@ -64,13 +69,15 @@ public abstract class SwapType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void startInBackground() {
|
public void startInBackground() {
|
||||||
|
start();
|
||||||
|
/**
|
||||||
new AsyncTask<Void, Void, Void>() {
|
new AsyncTask<Void, Void, Void>() {
|
||||||
@Override
|
@Override
|
||||||
protected Void doInBackground(Void... params) {
|
protected Void doInBackground(Void... params) {
|
||||||
start();
|
start();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}.execute();
|
}.execute();*/
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ensureRunning() {
|
public void ensureRunning() {
|
||||||
|
@ -3,6 +3,7 @@ package org.fdroid.fdroid.net;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import org.apache.commons.io.input.BoundedInputStream;
|
import org.apache.commons.io.input.BoundedInputStream;
|
||||||
|
import org.fdroid.fdroid.Utils;
|
||||||
import org.fdroid.fdroid.net.bluetooth.BluetoothClient;
|
import org.fdroid.fdroid.net.bluetooth.BluetoothClient;
|
||||||
import org.fdroid.fdroid.net.bluetooth.BluetoothConnection;
|
import org.fdroid.fdroid.net.bluetooth.BluetoothConnection;
|
||||||
import org.fdroid.fdroid.net.bluetooth.FileDetails;
|
import org.fdroid.fdroid.net.bluetooth.FileDetails;
|
||||||
@ -13,6 +14,8 @@ import java.io.File;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.nio.Buffer;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
|
||||||
public class BluetoothDownloader extends Downloader {
|
public class BluetoothDownloader extends Downloader {
|
||||||
|
|
||||||
@ -30,9 +33,11 @@ public class BluetoothDownloader extends Downloader {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InputStream getInputStream() throws IOException {
|
public InputStream getInputStream() throws IOException {
|
||||||
Response response = Request.createGET(sourcePath, connection).send();
|
Request request = Request.createGET(sourcePath, connection);
|
||||||
|
Response response = request.send();
|
||||||
fileDetails = response.toFileDetails();
|
fileDetails = response.toFileDetails();
|
||||||
|
|
||||||
|
|
||||||
// TODO: Manage the dependency which includes this class better?
|
// TODO: Manage the dependency which includes this class better?
|
||||||
// Right now, I only needed the one class from apache commons.
|
// Right now, I only needed the one class from apache commons.
|
||||||
// There are countless classes online which provide this functionality,
|
// There are countless classes online which provide this functionality,
|
||||||
@ -43,6 +48,7 @@ public class BluetoothDownloader extends Downloader {
|
|||||||
// to us).
|
// to us).
|
||||||
BoundedInputStream stream = new BoundedInputStream(response.toContentStream(), fileDetails.getFileSize());
|
BoundedInputStream stream = new BoundedInputStream(response.toContentStream(), fileDetails.getFileSize());
|
||||||
stream.setPropagateClose(false);
|
stream.setPropagateClose(false);
|
||||||
|
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,7 +82,8 @@ public class BluetoothDownloader extends Downloader {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void download() throws IOException, InterruptedException {
|
public void download() throws IOException, InterruptedException {
|
||||||
downloadFromStream();
|
downloadFromStream(1024);
|
||||||
|
connection.closeQuietly();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -89,4 +96,11 @@ public class BluetoothDownloader extends Downloader {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close ()
|
||||||
|
{
|
||||||
|
if (connection != null)
|
||||||
|
connection.closeQuietly();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,12 +7,15 @@ import android.util.Log;
|
|||||||
|
|
||||||
import org.fdroid.fdroid.Utils;
|
import org.fdroid.fdroid.Utils;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.io.Reader;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
|
||||||
@ -37,6 +40,7 @@ public abstract class Downloader {
|
|||||||
protected int totalBytes = 0;
|
protected int totalBytes = 0;
|
||||||
|
|
||||||
public abstract InputStream getInputStream() throws IOException;
|
public abstract InputStream getInputStream() throws IOException;
|
||||||
|
public abstract void close();
|
||||||
|
|
||||||
Downloader(Context context, URL url, File destFile)
|
Downloader(Context context, URL url, File destFile)
|
||||||
throws FileNotFoundException, MalformedURLException {
|
throws FileNotFoundException, MalformedURLException {
|
||||||
@ -98,7 +102,7 @@ public abstract class Downloader {
|
|||||||
|
|
||||||
public abstract boolean isCached();
|
public abstract boolean isCached();
|
||||||
|
|
||||||
protected void downloadFromStream() throws IOException, InterruptedException {
|
protected void downloadFromStream(int bufferSize) throws IOException, InterruptedException {
|
||||||
Utils.DebugLog(TAG, "Downloading from stream");
|
Utils.DebugLog(TAG, "Downloading from stream");
|
||||||
InputStream input = null;
|
InputStream input = null;
|
||||||
try {
|
try {
|
||||||
@ -108,7 +112,7 @@ public abstract class Downloader {
|
|||||||
// we were interrupted before proceeding to the download.
|
// we were interrupted before proceeding to the download.
|
||||||
throwExceptionIfInterrupted();
|
throwExceptionIfInterrupted();
|
||||||
|
|
||||||
copyInputToOutputStream(input);
|
copyInputToOutputStream(input, bufferSize);
|
||||||
} finally {
|
} finally {
|
||||||
Utils.closeQuietly(outputStream);
|
Utils.closeQuietly(outputStream);
|
||||||
Utils.closeQuietly(input);
|
Utils.closeQuietly(input);
|
||||||
@ -143,20 +147,30 @@ public abstract class Downloader {
|
|||||||
* keeping track of the number of bytes that have flowed through for the
|
* keeping track of the number of bytes that have flowed through for the
|
||||||
* progress counter.
|
* progress counter.
|
||||||
*/
|
*/
|
||||||
protected void copyInputToOutputStream(InputStream input) throws IOException, InterruptedException {
|
protected void copyInputToOutputStream(InputStream input, int bufferSize) throws IOException, InterruptedException {
|
||||||
|
|
||||||
byte[] buffer = new byte[Utils.BUFFER_SIZE];
|
|
||||||
int bytesRead = 0;
|
int bytesRead = 0;
|
||||||
this.totalBytes = totalDownloadSize();
|
this.totalBytes = totalDownloadSize();
|
||||||
|
byte[] buffer = new byte[bufferSize];
|
||||||
|
|
||||||
// Getting the total download size could potentially take time, depending on how
|
// Getting the total download size could potentially take time, depending on how
|
||||||
// it is implemented, so we may as well check this before we proceed.
|
// it is implemented, so we may as well check this before we proceed.
|
||||||
throwExceptionIfInterrupted();
|
throwExceptionIfInterrupted();
|
||||||
|
|
||||||
sendProgress(bytesRead, totalBytes);
|
sendProgress(bytesRead, totalBytes);
|
||||||
while (true) {
|
while (bytesRead < totalBytes) {
|
||||||
|
|
||||||
|
int count = -1;
|
||||||
|
|
||||||
|
if (input.available()>0) {
|
||||||
|
|
||||||
|
int readLength = Math.min(input.available(), buffer.length);
|
||||||
|
count = input.read(buffer, 0, readLength);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
count = input.read(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
int count = input.read(buffer);
|
|
||||||
throwExceptionIfInterrupted();
|
throwExceptionIfInterrupted();
|
||||||
|
|
||||||
if (count == -1) {
|
if (count == -1) {
|
||||||
@ -167,8 +181,10 @@ public abstract class Downloader {
|
|||||||
bytesRead += count;
|
bytesRead += count;
|
||||||
sendProgress(bytesRead, totalBytes);
|
sendProgress(bytesRead, totalBytes);
|
||||||
outputStream.write(buffer, 0, count);
|
outputStream.write(buffer, 0, count);
|
||||||
|
|
||||||
}
|
}
|
||||||
outputStream.flush();
|
outputStream.flush();
|
||||||
|
outputStream.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void sendProgress(int bytesRead, int totalBytes) {
|
protected void sendProgress(int bytesRead, int totalBytes) {
|
||||||
|
@ -9,10 +9,13 @@ import org.fdroid.fdroid.FDroidApp;
|
|||||||
import org.fdroid.fdroid.Preferences;
|
import org.fdroid.fdroid.Preferences;
|
||||||
import org.fdroid.fdroid.Utils;
|
import org.fdroid.fdroid.Utils;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
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.io.InputStreamReader;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
@ -31,6 +34,7 @@ public class HttpDownloader extends Downloader {
|
|||||||
protected static final String HEADER_FIELD_ETAG = "ETag";
|
protected static final String HEADER_FIELD_ETAG = "ETag";
|
||||||
|
|
||||||
protected HttpURLConnection connection;
|
protected HttpURLConnection connection;
|
||||||
|
private InputStream stream;
|
||||||
private int statusCode = -1;
|
private int statusCode = -1;
|
||||||
private boolean onlyStream = false;
|
private boolean onlyStream = false;
|
||||||
|
|
||||||
@ -58,10 +62,16 @@ public class HttpDownloader extends Downloader {
|
|||||||
* same one twice, bail with an exception).
|
* same one twice, bail with an exception).
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
@Override
|
|
||||||
public InputStream getInputStream() throws IOException {
|
public InputStream getInputStream() throws IOException {
|
||||||
setupConnection();
|
setupConnection();
|
||||||
return connection.getInputStream();
|
stream = new BufferedInputStream(connection.getInputStream());
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BufferedReader getBufferedReader () throws IOException
|
||||||
|
{
|
||||||
|
return new BufferedReader(new InputStreamReader(getInputStream()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get a remote file. Returns the HTTP response code.
|
// Get a remote file. Returns the HTTP response code.
|
||||||
@ -117,7 +127,7 @@ public class HttpDownloader extends Downloader {
|
|||||||
Utils.DebugLog(TAG, sourceUrl + " is cached, so not downloading (HTTP " + statusCode + ")");
|
Utils.DebugLog(TAG, sourceUrl + " is cached, so not downloading (HTTP " + statusCode + ")");
|
||||||
} else {
|
} else {
|
||||||
Utils.DebugLog(TAG, "Downloading from " + sourceUrl);
|
Utils.DebugLog(TAG, "Downloading from " + sourceUrl);
|
||||||
downloadFromStream();
|
downloadFromStream(4096);
|
||||||
updateCacheCheck();
|
updateCacheCheck();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -159,4 +169,14 @@ public class HttpDownloader extends Downloader {
|
|||||||
return statusCode;
|
return statusCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void close ()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (stream != null)
|
||||||
|
stream.close();
|
||||||
|
}
|
||||||
|
catch (IOException e) {}
|
||||||
|
|
||||||
|
connection.disconnect();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,10 @@ package org.fdroid.fdroid.net;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
import com.nostra13.universalimageloader.core.download.BaseImageDownloader;
|
import com.nostra13.universalimageloader.core.download.BaseImageDownloader;
|
||||||
|
import com.nostra13.universalimageloader.utils.IoUtils;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
@ -19,13 +22,41 @@ public class IconDownloader extends BaseImageDownloader {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InputStream getStream(String imageUri, Object extra) throws IOException {
|
public InputStream getStream(String imageUri, Object extra) throws IOException {
|
||||||
switch (Scheme.ofUri(imageUri)) {
|
|
||||||
case HTTP:
|
Scheme scheme = Scheme.ofUri(imageUri);
|
||||||
case HTTPS:
|
|
||||||
Downloader downloader = DownloaderFactory.create(context, imageUri);
|
switch (scheme) {
|
||||||
return downloader.getInputStream();
|
case HTTP:
|
||||||
default:
|
case HTTPS:
|
||||||
return super.getStream(imageUri, extra);
|
Downloader downloader = DownloaderFactory.create(context, imageUri);
|
||||||
|
return downloader.getInputStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//bluetooth isn't a scheme in the Scheme. library, so we can add a check here
|
||||||
|
if (imageUri.toLowerCase().startsWith("bluetooth"))
|
||||||
|
{
|
||||||
|
Downloader downloader = DownloaderFactory.create(context, imageUri);
|
||||||
|
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
InputStream is = downloader.getInputStream();
|
||||||
|
|
||||||
|
int b = -1;
|
||||||
|
|
||||||
|
while ((b = is.read())!=-1)
|
||||||
|
baos.write(b);
|
||||||
|
|
||||||
|
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
|
||||||
|
|
||||||
|
downloader.close();
|
||||||
|
|
||||||
|
return bais;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return super.getStream(imageUri, extra);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -25,13 +25,23 @@ public class BluetoothClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public BluetoothConnection openConnection() throws IOException {
|
public BluetoothConnection openConnection() throws IOException {
|
||||||
|
|
||||||
|
|
||||||
BluetoothSocket socket = null;
|
BluetoothSocket socket = null;
|
||||||
|
BluetoothConnection connection = null;
|
||||||
try {
|
try {
|
||||||
socket = device.createInsecureRfcommSocketToServiceRecord(BluetoothConstants.fdroidUuid());
|
socket = device.createInsecureRfcommSocketToServiceRecord(BluetoothConstants.fdroidUuid());
|
||||||
BluetoothConnection connection = new BluetoothConnection(socket);
|
connection = new BluetoothConnection(socket);
|
||||||
connection.open();
|
connection.open();
|
||||||
return connection;
|
return connection;
|
||||||
} catch (IOException e1) {
|
} catch (IOException e1) {
|
||||||
|
|
||||||
|
if (connection != null)
|
||||||
|
connection.closeQuietly();
|
||||||
|
|
||||||
|
throw e1;
|
||||||
|
|
||||||
|
/*
|
||||||
Log.e(TAG, "There was an error while establishing Bluetooth connection. Falling back to using reflection...");
|
Log.e(TAG, "There was an error while establishing Bluetooth connection. Falling back to using reflection...");
|
||||||
Class<?> clazz = socket.getRemoteDevice().getClass();
|
Class<?> clazz = socket.getRemoteDevice().getClass();
|
||||||
Class<?>[] paramTypes = new Class<?>[]{Integer.TYPE};
|
Class<?>[] paramTypes = new Class<?>[]{Integer.TYPE};
|
||||||
@ -41,6 +51,7 @@ public class BluetoothClient {
|
|||||||
method = clazz.getMethod("createInsecureRfcommSocket", paramTypes);
|
method = clazz.getMethod("createInsecureRfcommSocket", paramTypes);
|
||||||
Object[] params = new Object[]{1};
|
Object[] params = new Object[]{1};
|
||||||
BluetoothSocket sockFallback = (BluetoothSocket) method.invoke(socket.getRemoteDevice(), params);
|
BluetoothSocket sockFallback = (BluetoothSocket) method.invoke(socket.getRemoteDevice(), params);
|
||||||
|
|
||||||
BluetoothConnection connection = new BluetoothConnection(sockFallback);
|
BluetoothConnection connection = new BluetoothConnection(sockFallback);
|
||||||
connection.open();
|
connection.open();
|
||||||
return connection;
|
return connection;
|
||||||
@ -50,7 +61,7 @@ public class BluetoothClient {
|
|||||||
throw e1;
|
throw e1;
|
||||||
} catch (InvocationTargetException e) {
|
} catch (InvocationTargetException e) {
|
||||||
throw e1;
|
throw e1;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
// Don't catch exceptions this time, let it bubble up as we did our best but don't
|
// Don't catch exceptions this time, let it bubble up as we did our best but don't
|
||||||
// have anythign else to offer in terms of resolving the problem right now.
|
// have anythign else to offer in terms of resolving the problem right now.
|
||||||
|
@ -7,6 +7,8 @@ import android.os.Build;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import org.fdroid.fdroid.Utils;
|
import org.fdroid.fdroid.Utils;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.BufferedOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
@ -39,8 +41,8 @@ public class BluetoothConnection {
|
|||||||
socket.connect();
|
socket.connect();
|
||||||
}
|
}
|
||||||
|
|
||||||
input = socket.getInputStream();
|
input = new BufferedInputStream(socket.getInputStream());
|
||||||
output = socket.getOutputStream();
|
output = new BufferedOutputStream(socket.getOutputStream());
|
||||||
Log.d(TAG, "Opened connection to Bluetooth device");
|
Log.d(TAG, "Opened connection to Bluetooth device");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,12 +53,6 @@ public class BluetoothConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
if (input == null || output == null) {
|
closeQuietly();
|
||||||
throw new RuntimeException("Cannot close() a BluetoothConnection before calling open()" );
|
|
||||||
}
|
|
||||||
|
|
||||||
input.close();
|
|
||||||
output.close();
|
|
||||||
socket.close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -40,6 +40,8 @@ public class BluetoothServer extends Thread {
|
|||||||
public BluetoothServer(BluetoothSwap swap, File webRoot) {
|
public BluetoothServer(BluetoothSwap swap, File webRoot) {
|
||||||
this.webRoot = webRoot;
|
this.webRoot = webRoot;
|
||||||
this.swap = swap;
|
this.swap = swap;
|
||||||
|
|
||||||
|
start();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isRunning() { return isRunning; }
|
public boolean isRunning() { return isRunning; }
|
||||||
@ -81,7 +83,7 @@ public class BluetoothServer extends Thread {
|
|||||||
try {
|
try {
|
||||||
BluetoothSocket clientSocket = serverSocket.accept();
|
BluetoothSocket clientSocket = serverSocket.accept();
|
||||||
if (clientSocket != null) {
|
if (clientSocket != null) {
|
||||||
if (!isInterrupted()) {
|
if (isInterrupted()) {
|
||||||
Log.d(TAG, "Server stopped after socket accepted from client, but before initiating connection.");
|
Log.d(TAG, "Server stopped after socket accepted from client, but before initiating connection.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -135,6 +137,8 @@ public class BluetoothServer extends Thread {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
connection.closeQuietly();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response handleRequest(Request request) throws IOException {
|
private Response handleRequest(Request request) throws IOException {
|
||||||
|
@ -5,9 +5,14 @@ import org.fdroid.fdroid.net.bluetooth.BluetoothConnection;
|
|||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.BufferedWriter;
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.OutputStream;
|
||||||
import java.io.OutputStreamWriter;
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.io.Writer;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -27,16 +32,16 @@ public class Request {
|
|||||||
private Map<String, String> headers;
|
private Map<String, String> headers;
|
||||||
|
|
||||||
private BluetoothConnection connection;
|
private BluetoothConnection connection;
|
||||||
private BufferedWriter output;
|
private Writer output;
|
||||||
private BufferedReader input;
|
private InputStream input;
|
||||||
|
|
||||||
private Request(String method, String path, BluetoothConnection connection) {
|
private Request(String method, String path, BluetoothConnection connection) {
|
||||||
this.method = method;
|
this.method = method;
|
||||||
this.path = path;
|
this.path = path;
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
|
|
||||||
output = new BufferedWriter(new OutputStreamWriter(connection.getOutputStream()));
|
output = new OutputStreamWriter(connection.getOutputStream());
|
||||||
input = new BufferedReader(new InputStreamReader(connection.getInputStream()));
|
input = connection.getInputStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Request createHEAD(String path, BluetoothConnection connection)
|
public static Request createHEAD(String path, BluetoothConnection connection)
|
||||||
@ -93,7 +98,7 @@ public class Request {
|
|||||||
*/
|
*/
|
||||||
private boolean listen() throws IOException {
|
private boolean listen() throws IOException {
|
||||||
|
|
||||||
String requestLine = input.readLine();
|
String requestLine = readLine();
|
||||||
|
|
||||||
if (requestLine == null || requestLine.trim().length() == 0)
|
if (requestLine == null || requestLine.trim().length() == 0)
|
||||||
return false;
|
return false;
|
||||||
@ -125,11 +130,8 @@ public class Request {
|
|||||||
* a space, and then the status label (which may contain spaces).
|
* a space, and then the status label (which may contain spaces).
|
||||||
*/
|
*/
|
||||||
private int readResponseCode() throws IOException {
|
private int readResponseCode() throws IOException {
|
||||||
String line = input.readLine();
|
|
||||||
if (line == null) {
|
String line = readLine();
|
||||||
// TODO: What to do?
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Error handling
|
// TODO: Error handling
|
||||||
int firstSpace = line.indexOf(' ');
|
int firstSpace = line.indexOf(' ');
|
||||||
@ -139,6 +141,36 @@ public class Request {
|
|||||||
return Integer.parseInt(status);
|
return Integer.parseInt(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String readLine () throws IOException
|
||||||
|
{
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
String line = null;
|
||||||
|
|
||||||
|
while (line == null) {
|
||||||
|
|
||||||
|
while (input.available()>0) {
|
||||||
|
|
||||||
|
int b = input.read();
|
||||||
|
|
||||||
|
|
||||||
|
if (((char)b) == '\n') {
|
||||||
|
if (baos.size() > 0)
|
||||||
|
line = new String(baos.toByteArray());
|
||||||
|
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
|
baos.write(b);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
try { Thread.sleep(100); }
|
||||||
|
catch (Exception e){};
|
||||||
|
}
|
||||||
|
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subsequent lines (after the status line) represent the headers, which are case
|
* Subsequent lines (after the status line) represent the headers, which are case
|
||||||
* insensitive and may be multi-line. We don't deal with multi-line headers in
|
* insensitive and may be multi-line. We don't deal with multi-line headers in
|
||||||
@ -146,15 +178,22 @@ public class Request {
|
|||||||
*/
|
*/
|
||||||
private Map<String, String> readHeaders() throws IOException {
|
private Map<String, String> readHeaders() throws IOException {
|
||||||
Map<String, String> headers = new HashMap<>();
|
Map<String, String> headers = new HashMap<>();
|
||||||
String responseLine = input.readLine();
|
String responseLine = readLine();
|
||||||
while (responseLine != null && responseLine.length() > 0) {
|
while (responseLine != null) {
|
||||||
|
|
||||||
// TODO: Error handling
|
// TODO: Error handling
|
||||||
String[] parts = responseLine.split(":");
|
String[] parts = responseLine.split(":");
|
||||||
String header = parts[0].trim();
|
if (parts.length > 1) {
|
||||||
String value = parts[1].trim();
|
String header = parts[0].trim();
|
||||||
headers.put(header, value);
|
String value = parts[1].trim();
|
||||||
responseLine = input.readLine();
|
headers.put(header, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input.available()>0)
|
||||||
|
responseLine = readLine();
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
return headers;
|
return headers;
|
||||||
}
|
}
|
||||||
|
@ -282,7 +282,8 @@ public class SwapAppsView extends ListView implements
|
|||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
Apk apk = getApkToInstall();
|
Apk apk = getApkToInstall();
|
||||||
String broadcastUrl = intent.getStringExtra(Downloader.EXTRA_ADDRESS);
|
String broadcastUrl = intent.getStringExtra(Downloader.EXTRA_ADDRESS);
|
||||||
if (!TextUtils.equals(Utils.getApkUrl(apk.repoAddress, apk), broadcastUrl)) {
|
|
||||||
|
if (apk != null && apk.repoAddress != null && (!TextUtils.equals(Utils.getApkUrl(apk.repoAddress, apk), broadcastUrl))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -373,9 +374,15 @@ public class SwapAppsView extends ListView implements
|
|||||||
|
|
||||||
private void resetView() {
|
private void resetView() {
|
||||||
|
|
||||||
|
if (app == null)
|
||||||
|
return;
|
||||||
|
|
||||||
progressView.setVisibility(View.GONE);
|
progressView.setVisibility(View.GONE);
|
||||||
progressView.setIndeterminate(true);
|
progressView.setIndeterminate(true);
|
||||||
nameView.setText(app.name);
|
|
||||||
|
if (app.name != null)
|
||||||
|
nameView.setText(app.name);
|
||||||
|
|
||||||
ImageLoader.getInstance().displayImage(app.iconUrl, iconView, displayImageOptions);
|
ImageLoader.getInstance().displayImage(app.iconUrl, iconView, displayImageOptions);
|
||||||
|
|
||||||
btnInstall.setVisibility(View.GONE);
|
btnInstall.setVisibility(View.GONE);
|
||||||
|
@ -44,6 +44,7 @@ import org.fdroid.fdroid.data.NewRepoConfig;
|
|||||||
import org.fdroid.fdroid.installer.Installer;
|
import org.fdroid.fdroid.installer.Installer;
|
||||||
import org.fdroid.fdroid.localrepo.LocalRepoManager;
|
import org.fdroid.fdroid.localrepo.LocalRepoManager;
|
||||||
import org.fdroid.fdroid.localrepo.SwapService;
|
import org.fdroid.fdroid.localrepo.SwapService;
|
||||||
|
import org.fdroid.fdroid.localrepo.peers.BluetoothFinder;
|
||||||
import org.fdroid.fdroid.localrepo.peers.Peer;
|
import org.fdroid.fdroid.localrepo.peers.Peer;
|
||||||
import org.fdroid.fdroid.net.ApkDownloader;
|
import org.fdroid.fdroid.net.ApkDownloader;
|
||||||
|
|
||||||
@ -625,7 +626,7 @@ public class SwapWorkflowActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
Log.d(TAG, "Not currently in discoverable mode, so prompting user to enable.");
|
Log.d(TAG, "Not currently in discoverable mode, so prompting user to enable.");
|
||||||
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
|
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
|
||||||
intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300); // TODO: What about when this expires? What if user manually disables discovery?
|
intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, BluetoothFinder.DISCOVERABLE_TIMEOUT); // 3600 is new maximum! TODO: What about when this expires? What if user manually disables discovery?
|
||||||
startActivityForResult(intent, REQUEST_BLUETOOTH_DISCOVERABLE);
|
startActivityForResult(intent, REQUEST_BLUETOOTH_DISCOVERABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user