mirror of https://github.com/YTVanced/VancedMicroG
Improve mcs connection
wake up device when reconnecting, fix teardown incomplete on null message (#24)
This commit is contained in:
parent
c826702bb9
commit
1a83f8281f
|
@ -55,7 +55,7 @@
|
||||||
<permission
|
<permission
|
||||||
android:name="org.microg.gms.STATUS_BROADCAST"
|
android:name="org.microg.gms.STATUS_BROADCAST"
|
||||||
android:label="@string/perm_status_broadcast_label"
|
android:label="@string/perm_status_broadcast_label"
|
||||||
android:protectionLevel="dangerous" />
|
android:protectionLevel="normal" />
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.FAKE_PACKAGE_SIGNATURE" />
|
<uses-permission android:name="android.permission.FAKE_PACKAGE_SIGNATURE" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
|
|
|
@ -42,6 +42,7 @@ import static org.microg.gms.gcm.Constants.MCS_LOGIN_REQUEST_TAG;
|
||||||
import static org.microg.gms.gcm.Constants.MCS_LOGIN_RESPONSE_TAG;
|
import static org.microg.gms.gcm.Constants.MCS_LOGIN_RESPONSE_TAG;
|
||||||
import static org.microg.gms.gcm.Constants.MSG_INPUT;
|
import static org.microg.gms.gcm.Constants.MSG_INPUT;
|
||||||
import static org.microg.gms.gcm.Constants.MSG_INPUT_ERROR;
|
import static org.microg.gms.gcm.Constants.MSG_INPUT_ERROR;
|
||||||
|
import static org.microg.gms.gcm.Constants.MSG_TEARDOWN;
|
||||||
|
|
||||||
public class McsInputStream extends Thread {
|
public class McsInputStream extends Thread {
|
||||||
private static final String TAG = "GmsGcmMcsInput";
|
private static final String TAG = "GmsGcmMcsInput";
|
||||||
|
@ -70,15 +71,20 @@ public class McsInputStream extends Thread {
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
while (!Thread.currentThread().isInterrupted()) {
|
while (!Thread.currentThread().isInterrupted()) {
|
||||||
mainHandler.dispatchMessage(mainHandler.obtainMessage(MSG_INPUT, read()));
|
Message msg = read();
|
||||||
|
if (msg != null) {
|
||||||
|
mainHandler.dispatchMessage(mainHandler.obtainMessage(MSG_INPUT, msg));
|
||||||
|
} else {
|
||||||
|
mainHandler.dispatchMessage(mainHandler.obtainMessage(MSG_TEARDOWN, "null message"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
try {
|
|
||||||
is.close();
|
|
||||||
} catch (IOException ignored) {
|
|
||||||
}
|
|
||||||
mainHandler.dispatchMessage(mainHandler.obtainMessage(MSG_INPUT_ERROR, e));
|
mainHandler.dispatchMessage(mainHandler.obtainMessage(MSG_INPUT_ERROR, e));
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
is.close();
|
||||||
|
} catch (IOException ignored) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void close() {
|
public void close() {
|
||||||
|
@ -115,7 +121,10 @@ public class McsInputStream extends Thread {
|
||||||
ensureVersionRead();
|
ensureVersionRead();
|
||||||
int mcsTag = is.read();
|
int mcsTag = is.read();
|
||||||
int mcsSize = readVarint();
|
int mcsSize = readVarint();
|
||||||
if (mcsTag < 0 || mcsSize < 0) return null;
|
if (mcsTag < 0 || mcsSize < 0) {
|
||||||
|
Log.w(TAG, "mcsTag: " + mcsTag + " mcsSize: " + mcsSize);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
byte[] bytes = new byte[mcsSize];
|
byte[] bytes = new byte[mcsSize];
|
||||||
int len = 0, read = 0;
|
int len = 0, read = 0;
|
||||||
while (len < mcsSize && read >= 0) {
|
while (len < mcsSize && read >= 0) {
|
||||||
|
|
|
@ -26,6 +26,7 @@ import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
|
import android.support.v4.content.WakefulBroadcastReceiver;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.squareup.wire.Message;
|
import com.squareup.wire.Message;
|
||||||
|
@ -82,12 +83,15 @@ public class McsService extends IntentService implements Handler.Callback {
|
||||||
|
|
||||||
private static MainThread mainThread;
|
private static MainThread mainThread;
|
||||||
private static Handler mainHandler;
|
private static Handler mainHandler;
|
||||||
private boolean initialized = false;
|
|
||||||
|
|
||||||
private AlarmManager alarmManager;
|
private AlarmManager alarmManager;
|
||||||
private PowerManager powerManager;
|
private PowerManager powerManager;
|
||||||
private static PowerManager.WakeLock wakeLock;
|
private static PowerManager.WakeLock wakeLock;
|
||||||
|
|
||||||
|
private static int delay = 0;
|
||||||
|
|
||||||
|
private Intent connectIntent;
|
||||||
|
|
||||||
public McsService() {
|
public McsService() {
|
||||||
super(TAG);
|
super(TAG);
|
||||||
}
|
}
|
||||||
|
@ -96,8 +100,15 @@ public class McsService extends IntentService implements Handler.Callback {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
Looper.prepare();
|
Looper.prepare();
|
||||||
mainHandler = new Handler(Looper.myLooper(), McsService.this);
|
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "mcs");
|
||||||
mainHandler.dispatchMessage(mainHandler.obtainMessage(MSG_CONNECT));
|
wakeLock.setReferenceCounted(false);
|
||||||
|
synchronized (McsService.class) {
|
||||||
|
mainHandler = new Handler(Looper.myLooper(), McsService.this);
|
||||||
|
if (connectIntent != null) {
|
||||||
|
mainHandler.dispatchMessage(mainHandler.obtainMessage(MSG_CONNECT, connectIntent));
|
||||||
|
WakefulBroadcastReceiver.completeWakefulIntent(connectIntent);
|
||||||
|
}
|
||||||
|
}
|
||||||
Looper.loop();
|
Looper.loop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -105,36 +116,42 @@ public class McsService extends IntentService implements Handler.Callback {
|
||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
if (mainThread == null) {
|
|
||||||
mainThread = new MainThread();
|
|
||||||
mainThread.start();
|
|
||||||
}
|
|
||||||
heartbeatIntent = PendingIntent.getService(this, 0, new Intent(ACTION_HEARTBEAT, null, this, McsService.class), 0);
|
heartbeatIntent = PendingIntent.getService(this, 0, new Intent(ACTION_HEARTBEAT, null, this, McsService.class), 0);
|
||||||
alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
|
alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
|
||||||
powerManager = (PowerManager) getSystemService(POWER_SERVICE);
|
powerManager = (PowerManager) getSystemService(POWER_SERVICE);
|
||||||
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "mcs");
|
synchronized (McsService.class) {
|
||||||
wakeLock.setReferenceCounted(false);
|
if (mainThread == null) {
|
||||||
|
mainThread = new MainThread();
|
||||||
alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + HEARTBEAT_MS, HEARTBEAT_MS, heartbeatIntent);
|
mainThread.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isConnected() {
|
public synchronized static boolean isConnected() {
|
||||||
return inputStream != null && inputStream.isAlive() && outputStream != null && outputStream.isAlive();
|
return inputStream != null && inputStream.isAlive() && outputStream != null && outputStream.isAlive();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onHandleIntent(Intent intent) {
|
protected void onHandleIntent(Intent intent) {
|
||||||
wakeLock.acquire();
|
synchronized (McsService.class) {
|
||||||
if (mainHandler != null) {
|
if (mainHandler != null) {
|
||||||
if (ACTION_CONNECT.equals(intent.getAction())) {
|
wakeLock.acquire();
|
||||||
mainHandler.dispatchMessage(mainHandler.obtainMessage(MSG_CONNECT, intent));
|
if (ACTION_CONNECT.equals(intent.getAction())) {
|
||||||
} else if (ACTION_HEARTBEAT.equals(intent.getAction())) {
|
mainHandler.dispatchMessage(mainHandler.obtainMessage(MSG_CONNECT, intent));
|
||||||
mainHandler.dispatchMessage(mainHandler.obtainMessage(MSG_HEARTBEAT, intent));
|
} else if (ACTION_HEARTBEAT.equals(intent.getAction())) {
|
||||||
|
mainHandler.dispatchMessage(mainHandler.obtainMessage(MSG_HEARTBEAT, intent));
|
||||||
|
}
|
||||||
|
WakefulBroadcastReceiver.completeWakefulIntent(intent);
|
||||||
|
} else if (connectIntent == null) {
|
||||||
|
connectIntent = intent;
|
||||||
|
} else {
|
||||||
|
WakefulBroadcastReceiver.completeWakefulIntent(intent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void connect() {
|
private synchronized void connect() {
|
||||||
|
if (delay < 60000) delay += 5000;
|
||||||
try {
|
try {
|
||||||
Log.d(TAG, "Starting MCS connection...");
|
Log.d(TAG, "Starting MCS connection...");
|
||||||
Socket socket = new Socket(SERVICE_HOST, SERVICE_PORT);
|
Socket socket = new Socket(SERVICE_HOST, SERVICE_PORT);
|
||||||
|
@ -145,6 +162,8 @@ public class McsService extends IntentService implements Handler.Callback {
|
||||||
outputStream = new McsOutputStream(sslSocket.getOutputStream(), mainHandler);
|
outputStream = new McsOutputStream(sslSocket.getOutputStream(), mainHandler);
|
||||||
inputStream.start();
|
inputStream.start();
|
||||||
outputStream.start();
|
outputStream.start();
|
||||||
|
|
||||||
|
alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime(), HEARTBEAT_MS, heartbeatIntent);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.w(TAG, "Exception while connecting!", e);
|
Log.w(TAG, "Exception while connecting!", e);
|
||||||
mainHandler.dispatchMessage(mainHandler.obtainMessage(MSG_TEARDOWN, e));
|
mainHandler.dispatchMessage(mainHandler.obtainMessage(MSG_TEARDOWN, e));
|
||||||
|
@ -260,11 +279,7 @@ public class McsService extends IntentService implements Handler.Callback {
|
||||||
switch (msg.what) {
|
switch (msg.what) {
|
||||||
case MSG_INPUT:
|
case MSG_INPUT:
|
||||||
Log.d(TAG, "Incoming message: " + msg.obj);
|
Log.d(TAG, "Incoming message: " + msg.obj);
|
||||||
if (msg.obj != null) {
|
handleInput((Message) msg.obj);
|
||||||
handleInput((Message) msg.obj);
|
|
||||||
} else {
|
|
||||||
mainHandler.dispatchMessage(mainHandler.obtainMessage(MSG_TEARDOWN, "null message"));
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
case MSG_OUTPUT:
|
case MSG_OUTPUT:
|
||||||
Log.d(TAG, "Outgoing message: " + msg.obj);
|
Log.d(TAG, "Outgoing message: " + msg.obj);
|
||||||
|
@ -321,6 +336,7 @@ public class McsService extends IntentService implements Handler.Callback {
|
||||||
} else {
|
} else {
|
||||||
Log.w(TAG, "Unknown message: " + message);
|
Log.w(TAG, "Unknown message: " + message);
|
||||||
}
|
}
|
||||||
|
delay = 0;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
mainHandler.dispatchMessage(mainHandler.obtainMessage(MSG_TEARDOWN, e));
|
mainHandler.dispatchMessage(mainHandler.obtainMessage(MSG_TEARDOWN, e));
|
||||||
}
|
}
|
||||||
|
@ -330,13 +346,20 @@ public class McsService extends IntentService implements Handler.Callback {
|
||||||
sendOutputStream(MSG_TEARDOWN, msg.obj);
|
sendOutputStream(MSG_TEARDOWN, msg.obj);
|
||||||
if (inputStream != null) {
|
if (inputStream != null) {
|
||||||
inputStream.close();
|
inputStream.close();
|
||||||
|
inputStream = null;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
sslSocket.close();
|
sslSocket.close();
|
||||||
} catch (Exception ignored) {
|
} catch (Exception ignored) {
|
||||||
}
|
}
|
||||||
sendBroadcast(new Intent("org.microg.gms.gcm.RECONNECT"), "org.microg.gms.STATUS_BROADCAST");
|
if (delay == 0) {
|
||||||
|
sendBroadcast(new Intent("org.microg.gms.gcm.RECONNECT"), "org.microg.gms.STATUS_BROADCAST");
|
||||||
|
} else {
|
||||||
|
alarmManager.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + delay, PendingIntent.getBroadcast(this, 1, new Intent(this, TriggerReceiver.class), 0));
|
||||||
|
}
|
||||||
alarmManager.cancel(heartbeatIntent);
|
alarmManager.cancel(heartbeatIntent);
|
||||||
wakeLock.release();
|
if (wakeLock != null) {
|
||||||
|
wakeLock.release();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,35 +16,37 @@
|
||||||
|
|
||||||
package org.microg.gms.gcm;
|
package org.microg.gms.gcm;
|
||||||
|
|
||||||
import android.app.AlarmManager;
|
|
||||||
import android.app.PendingIntent;
|
|
||||||
import android.content.BroadcastReceiver;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
import android.net.NetworkInfo;
|
import android.net.NetworkInfo;
|
||||||
import android.os.SystemClock;
|
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
|
import android.support.v4.content.WakefulBroadcastReceiver;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
public class TriggerReceiver extends BroadcastReceiver {
|
public class TriggerReceiver extends WakefulBroadcastReceiver {
|
||||||
|
private static final String TAG = "GmsGcmTrigger";
|
||||||
private static final String PREF_ENABLE_GCM = "gcm_enable_mcs_service";
|
private static final String PREF_ENABLE_GCM = "gcm_enable_mcs_service";
|
||||||
private static final long pendingDelay = 1000;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
boolean force = "android.provider.Telephony.SECRET_CODE".equals(intent.getAction());
|
boolean force = "android.provider.Telephony.SECRET_CODE".equals(intent.getAction());
|
||||||
|
|
||||||
if (!McsService.isConnected() || force) {
|
if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean(PREF_ENABLE_GCM, false) || force) {
|
||||||
if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean(PREF_ENABLE_GCM, false) || force) {
|
if (!McsService.isConnected() || force) {
|
||||||
|
|
||||||
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||||
NetworkInfo networkInfo = cm.getActiveNetworkInfo();
|
NetworkInfo networkInfo = cm.getActiveNetworkInfo();
|
||||||
if (networkInfo != null && networkInfo.isConnected() || force) {
|
if (networkInfo != null && networkInfo.isConnected() || force) {
|
||||||
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
startWakefulService(context, new Intent(McsService.ACTION_CONNECT, null, context, McsService.class));
|
||||||
PendingIntent pendingIntent = PendingIntent.getService(context, 0, new Intent(McsService.ACTION_CONNECT, null, context, McsService.class), 0);
|
} else {
|
||||||
alarmManager.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + pendingDelay, pendingIntent);
|
Log.d(TAG, "Ignoring " + intent + ": network is offline");
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
Log.d(TAG, "Ignoring " + intent + ": service is running");
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
Log.d(TAG, "Ignoring " + intent + ": gcm is disabled");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue