related to #404 improvement to patterns to support close and discoverable
You must, must, must close the BT sockets else you run out of them. This code tries to handle all the places where BT sockets may not get closed. It also tries to tweak user experience/UI integration pieces in a few areas, and handle some NPEs that can occur when BT fails.
This commit is contained in:
parent
0a96d17dd1
commit
b3f8ac0a5b
@ -98,7 +98,9 @@ public class RepoUpdater {
|
||||
} catch (IOException e) {
|
||||
if (downloader != null && downloader.getFile() != null) {
|
||||
downloader.getFile().delete();
|
||||
downloader.close();
|
||||
}
|
||||
|
||||
throw new UpdateException(repo, "Error getting index file from " + repo.address, e);
|
||||
}
|
||||
return downloader;
|
||||
@ -121,6 +123,8 @@ public class RepoUpdater {
|
||||
// successful download, then we will have a file ready to use:
|
||||
processDownloadedFile(downloader.getFile(), downloader.getCacheTag());
|
||||
}
|
||||
|
||||
downloader.close();
|
||||
}
|
||||
|
||||
protected void processDownloadedFile(File downloadedFile, String cacheTag) throws UpdateException {
|
||||
|
@ -456,7 +456,7 @@ public class SwapService extends Service {
|
||||
}
|
||||
|
||||
public boolean isBluetoothDiscoverable() {
|
||||
return bluetoothSwap.isConnected();
|
||||
return bluetoothSwap.isDiscoverable();
|
||||
}
|
||||
|
||||
public boolean isBonjourDiscoverable() {
|
||||
|
@ -15,6 +15,8 @@ public class BluetoothFinder extends PeerFinder<BluetoothPeer> {
|
||||
|
||||
private static final String TAG = "BluetoothFinder";
|
||||
|
||||
public final static int DISCOVERABLE_TIMEOUT = 3600;
|
||||
|
||||
private final BluetoothAdapter adapter;
|
||||
|
||||
public BluetoothFinder(Context context) {
|
||||
|
@ -23,6 +23,7 @@ public class BluetoothSwap extends SwapType {
|
||||
@NonNull
|
||||
private final BluetoothAdapter adapter;
|
||||
private BroadcastReceiver receiver;
|
||||
private boolean isDiscoverable = false;
|
||||
|
||||
@Nullable
|
||||
private BluetoothServer server;
|
||||
@ -48,6 +49,11 @@ public class BluetoothSwap extends SwapType {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDiscoverable () {
|
||||
return isDiscoverable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConnected() {
|
||||
return server != null && server.isRunning() && super.isConnected();
|
||||
@ -68,6 +74,7 @@ public class BluetoothSwap extends SwapType {
|
||||
break;
|
||||
|
||||
case BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE:
|
||||
isDiscoverable = true;
|
||||
if (server != null && server.isRunning()) {
|
||||
setConnected(true);
|
||||
}
|
||||
@ -163,5 +170,6 @@ public class BluetoothSwap extends SwapType {
|
||||
protected String getBroadcastAction() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -33,6 +33,11 @@ public abstract class SwapType {
|
||||
|
||||
abstract protected String getBroadcastAction();
|
||||
|
||||
public boolean isDiscoverable ()
|
||||
{
|
||||
return isConnected();
|
||||
}
|
||||
|
||||
protected final void setConnected(boolean connected) {
|
||||
if (connected) {
|
||||
isConnected = true;
|
||||
|
@ -48,6 +48,7 @@ public class BluetoothDownloader extends Downloader {
|
||||
// to us).
|
||||
BoundedInputStream stream = new BoundedInputStream(response.toContentStream(), fileDetails.getFileSize());
|
||||
stream.setPropagateClose(false);
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
@ -95,4 +96,11 @@ public class BluetoothDownloader extends Downloader {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close ()
|
||||
{
|
||||
if (connection != null)
|
||||
connection.closeQuietly();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ public abstract class Downloader {
|
||||
protected int totalBytes = 0;
|
||||
|
||||
public abstract InputStream getInputStream() throws IOException;
|
||||
public abstract void close();
|
||||
|
||||
Downloader(Context context, URL url, File destFile)
|
||||
throws FileNotFoundException, MalformedURLException {
|
||||
|
@ -167,4 +167,8 @@ public class HttpDownloader extends Downloader {
|
||||
return statusCode;
|
||||
}
|
||||
|
||||
public void close ()
|
||||
{
|
||||
connection.disconnect();
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,10 @@ package org.fdroid.fdroid.net;
|
||||
import android.content.Context;
|
||||
|
||||
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.InputStream;
|
||||
|
||||
@ -33,11 +36,27 @@ public class IconDownloader extends BaseImageDownloader {
|
||||
if (imageUri.toLowerCase().startsWith("bluetooth"))
|
||||
{
|
||||
Downloader downloader = DownloaderFactory.create(context, imageUri);
|
||||
return downloader.getInputStream();
|
||||
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -28,12 +28,20 @@ public class BluetoothClient {
|
||||
|
||||
|
||||
BluetoothSocket socket = null;
|
||||
BluetoothConnection connection = null;
|
||||
try {
|
||||
socket = device.createInsecureRfcommSocketToServiceRecord(BluetoothConstants.fdroidUuid());
|
||||
BluetoothConnection connection = new BluetoothConnection(socket);
|
||||
connection = new BluetoothConnection(socket);
|
||||
connection.open();
|
||||
return connection;
|
||||
} 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...");
|
||||
Class<?> clazz = socket.getRemoteDevice().getClass();
|
||||
Class<?>[] paramTypes = new Class<?>[]{Integer.TYPE};
|
||||
@ -43,6 +51,7 @@ public class BluetoothClient {
|
||||
method = clazz.getMethod("createInsecureRfcommSocket", paramTypes);
|
||||
Object[] params = new Object[]{1};
|
||||
BluetoothSocket sockFallback = (BluetoothSocket) method.invoke(socket.getRemoteDevice(), params);
|
||||
|
||||
BluetoothConnection connection = new BluetoothConnection(sockFallback);
|
||||
connection.open();
|
||||
return connection;
|
||||
@ -52,7 +61,7 @@ public class BluetoothClient {
|
||||
throw e1;
|
||||
} catch (InvocationTargetException e) {
|
||||
throw e1;
|
||||
}
|
||||
}*/
|
||||
|
||||
// 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.
|
||||
|
@ -53,12 +53,6 @@ public class BluetoothConnection {
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
if (input == null || output == null) {
|
||||
throw new RuntimeException("Cannot close() a BluetoothConnection before calling open()" );
|
||||
}
|
||||
|
||||
input.close();
|
||||
output.close();
|
||||
socket.close();
|
||||
closeQuietly();
|
||||
}
|
||||
}
|
@ -137,6 +137,8 @@ public class BluetoothServer extends Thread {
|
||||
break;
|
||||
}
|
||||
|
||||
connection.closeQuietly();
|
||||
|
||||
}
|
||||
|
||||
private Response handleRequest(Request request) throws IOException {
|
||||
|
@ -283,7 +283,7 @@ public class SwapAppsView extends ListView implements
|
||||
Apk apk = getApkToInstall();
|
||||
String broadcastUrl = intent.getStringExtra(Downloader.EXTRA_ADDRESS);
|
||||
|
||||
if (apk.repoAddress != null && (!TextUtils.equals(Utils.getApkUrl(apk.repoAddress, apk), broadcastUrl))) {
|
||||
if (apk != null && apk.repoAddress != null && (!TextUtils.equals(Utils.getApkUrl(apk.repoAddress, apk), broadcastUrl))) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -374,9 +374,15 @@ public class SwapAppsView extends ListView implements
|
||||
|
||||
private void resetView() {
|
||||
|
||||
if (app == null)
|
||||
return;
|
||||
|
||||
progressView.setVisibility(View.GONE);
|
||||
progressView.setIndeterminate(true);
|
||||
nameView.setText(app.name);
|
||||
|
||||
if (app.name != null)
|
||||
nameView.setText(app.name);
|
||||
|
||||
ImageLoader.getInstance().displayImage(app.iconUrl, iconView, displayImageOptions);
|
||||
|
||||
btnInstall.setVisibility(View.GONE);
|
||||
|
@ -44,6 +44,7 @@ import org.fdroid.fdroid.data.NewRepoConfig;
|
||||
import org.fdroid.fdroid.installer.Installer;
|
||||
import org.fdroid.fdroid.localrepo.LocalRepoManager;
|
||||
import org.fdroid.fdroid.localrepo.SwapService;
|
||||
import org.fdroid.fdroid.localrepo.peers.BluetoothFinder;
|
||||
import org.fdroid.fdroid.localrepo.peers.Peer;
|
||||
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.");
|
||||
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
|
||||
intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 3600); // 3600 is new maximum! 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);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user