Ensure all threads to be closed

Fixes possible OOM error
This commit is contained in:
Marvin W 2016-05-18 14:10:17 +02:00
parent db013606e0
commit 70119087fe
No known key found for this signature in database
GPG Key ID: 072E9235DB996F2A
3 changed files with 44 additions and 22 deletions

View File

@ -30,6 +30,7 @@ import org.microg.gms.gcm.mcs.IqStanza;
import org.microg.gms.gcm.mcs.LoginRequest;
import org.microg.gms.gcm.mcs.LoginResponse;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
@ -44,7 +45,7 @@ import static org.microg.gms.gcm.McsConstants.MSG_INPUT;
import static org.microg.gms.gcm.McsConstants.MSG_INPUT_ERROR;
import static org.microg.gms.gcm.McsConstants.MSG_TEARDOWN;
public class McsInputStream extends Thread {
public class McsInputStream extends Thread implements Closeable {
private static final String TAG = "GmsGcmMcsInput";
private final InputStream is;
@ -56,6 +57,8 @@ public class McsInputStream extends Thread {
private int streamId = 0;
private long lastMsgTime = 0;
private boolean closed = false;
public McsInputStream(InputStream is, Handler mainHandler) {
this(is, mainHandler, false);
}
@ -70,7 +73,7 @@ public class McsInputStream extends Thread {
@Override
public void run() {
try {
while (!Thread.currentThread().isInterrupted()) {
while (!Thread.currentThread().isInterrupted() && !closed) {
android.os.Message msg = read();
if (msg != null) {
mainHandler.dispatchMessage(msg);
@ -88,8 +91,12 @@ public class McsInputStream extends Thread {
}
}
@Override
public void close() {
interrupt();
if (!closed) {
closed = true;
interrupt();
}
}
public int getStreamId() {

View File

@ -22,18 +22,10 @@ import android.util.Log;
import com.squareup.wire.Message;
import org.microg.gms.gcm.mcs.DataMessageStanza;
import org.microg.gms.gcm.mcs.HeartbeatAck;
import org.microg.gms.gcm.mcs.HeartbeatPing;
import org.microg.gms.gcm.mcs.LoginRequest;
import java.io.Closeable;
import java.io.IOException;
import java.io.OutputStream;
import static org.microg.gms.gcm.McsConstants.MCS_DATA_MESSAGE_STANZA_TAG;
import static org.microg.gms.gcm.McsConstants.MCS_HEARTBEAT_ACK_TAG;
import static org.microg.gms.gcm.McsConstants.MCS_HEARTBEAT_PING_TAG;
import static org.microg.gms.gcm.McsConstants.MCS_LOGIN_REQUEST_TAG;
import static org.microg.gms.gcm.McsConstants.MCS_VERSION_CODE;
import static org.microg.gms.gcm.McsConstants.MSG_OUTPUT;
import static org.microg.gms.gcm.McsConstants.MSG_OUTPUT_DONE;
@ -41,7 +33,7 @@ import static org.microg.gms.gcm.McsConstants.MSG_OUTPUT_ERROR;
import static org.microg.gms.gcm.McsConstants.MSG_OUTPUT_READY;
import static org.microg.gms.gcm.McsConstants.MSG_TEARDOWN;
public class McsOutputStream extends Thread implements Handler.Callback {
public class McsOutputStream extends Thread implements Handler.Callback, Closeable {
private static final String TAG = "GmsGcmMcsOutput";
private final OutputStream os;
@ -52,6 +44,8 @@ public class McsOutputStream extends Thread implements Handler.Callback {
private Handler mainHandler;
private Handler myHandler;
private boolean closed = false;
public McsOutputStream(OutputStream os, Handler mainHandler) {
this(os, mainHandler, false);
}
@ -101,6 +95,15 @@ public class McsOutputStream extends Thread implements Handler.Callback {
return false;
}
@Override
public void close() {
if (!closed) {
closed = true;
myHandler.getLooper().quit();
interrupt();
}
}
private synchronized void writeInternal(Message message, int tag) throws IOException {
if (!initialized) {
Log.d(TAG, "Write MCS version code: " + version);

View File

@ -45,6 +45,7 @@ import org.microg.gms.gcm.mcs.LoginRequest;
import org.microg.gms.gcm.mcs.LoginResponse;
import org.microg.gms.gcm.mcs.Setting;
import java.io.Closeable;
import java.net.Socket;
import java.util.Collections;
import java.util.List;
@ -56,8 +57,6 @@ import static android.os.Build.VERSION.SDK_INT;
import static org.microg.gms.gcm.GcmConstants.ACTION_C2DM_RECEIVE;
import static org.microg.gms.gcm.GcmConstants.EXTRA_COLLAPSE_KEY;
import static org.microg.gms.gcm.GcmConstants.EXTRA_FROM;
import static org.microg.gms.gcm.GcmConstants.EXTRA_MESSAGE_TYPE;
import static org.microg.gms.gcm.GcmConstants.MESSAGE_TYPE_GCM;
import static org.microg.gms.gcm.McsConstants.ACTION_CONNECT;
import static org.microg.gms.gcm.McsConstants.ACTION_HEARTBEAT;
import static org.microg.gms.gcm.McsConstants.ACTION_RECONNECT;
@ -110,6 +109,11 @@ public class McsService extends Service implements Handler.Callback {
private Intent connectIntent;
private class HandlerThread extends Thread {
public HandlerThread() {
setName("McsHandler");
}
@Override
public void run() {
Looper.prepare();
@ -155,8 +159,8 @@ public class McsService extends Service implements Handler.Callback {
return false;
}
// consider connection to be dead if we did not receive an ack within twice the heartbeat interval
if (SystemClock.elapsedRealtime() - lastHeartbeatAckElapsedRealtime < 2 * GcmPrefs.get(null).getHeartbeatMs()) {
logd("No heartbeat for " + 2 * GcmPrefs.get(null).getHeartbeatMs() / 1000 + " seconds, connection seems to be dead.");
if (SystemClock.elapsedRealtime() - lastHeartbeatAckElapsedRealtime > 2 * GcmPrefs.get(null).getHeartbeatMs()) {
logd("No heartbeat for " + (SystemClock.elapsedRealtime() - lastHeartbeatAckElapsedRealtime) / 1000 + " seconds, connection assumed to be dead after " + 2 * GcmPrefs.get(null).getHeartbeatMs() / 1000 + " seconds");
return false;
}
return true;
@ -222,6 +226,8 @@ public class McsService extends Service implements Handler.Callback {
private synchronized void connect() {
try {
tryClose(inputStream);
tryClose(outputStream);
logd("Starting MCS connection...");
Socket socket = new Socket(SERVICE_HOST, SERVICE_PORT);
logd("Connected to " + SERVICE_HOST + ":" + SERVICE_PORT);
@ -434,12 +440,18 @@ public class McsService extends Service implements Handler.Callback {
}
}
private void handleTeardown(android.os.Message msg) {
sendOutputStream(MSG_TEARDOWN, msg.arg1, msg.obj);
if (inputStream != null) {
inputStream.close();
inputStream = null;
private void tryClose(Closeable closeable) {
if (closeable != null) {
try {
closeable.close();
} catch (Exception ignored) {
}
}
}
private void handleTeardown(android.os.Message msg) {
tryClose(inputStream);
tryClose(outputStream);
try {
sslSocket.close();
} catch (Exception ignored) {