diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/MQTTUtils.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/MQTTUtils.java index ddf484f9d..605a406d2 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/MQTTUtils.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/MQTTUtils.java @@ -21,6 +21,7 @@ package org.eehouse.android.xw4; import android.content.Context; +import android.os.Build; import org.eclipse.paho.client.mqttv3.IMqttActionListener; import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken; @@ -34,6 +35,10 @@ import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.atomic.AtomicReference; +import javax.net.ssl.HttpsURLConnection; + +import org.json.JSONException; +import org.json.JSONObject; import org.eehouse.android.xw4.jni.CommsAddrRec; import org.eehouse.android.xw4.jni.CommsAddrRec.CommsConnType; @@ -42,7 +47,10 @@ import org.eehouse.android.xw4.loc.LocUtils; public class MQTTUtils extends Thread implements IMqttActionListener, MqttCallbackExtended { private static final String TAG = MQTTUtils.class.getSimpleName(); + private static final String KEY_NEXT_REG = TAG + "/next_reg"; + private static AtomicReference sInstance = new AtomicReference<>(); + private static long sNextReg = 0; private MqttAsyncClient mClient; private long mPauseTime = 0L; @@ -169,6 +177,7 @@ public class MQTTUtils extends Thread implements IMqttActionListener, MqttCallba mContext = context; String[] topic = {null}; mDevID = XwJNI.dvc_getMQTTDevID( topic ); + Assert.assertTrueNR( 16 == mDevID.length() ); mTopic = topic[0]; mMsgThread = new MsgThread(); @@ -222,6 +231,55 @@ public class MQTTUtils extends Thread implements IMqttActionListener, MqttCallba ise.printStackTrace(); clearInstance(); } + + registerOnce(); + } + + private void registerOnce() + { + if ( 0 == sNextReg ) { + sNextReg = DBUtils.getLongFor( mContext, KEY_NEXT_REG, 1 ); + } + long now = Utils.getCurSeconds(); + Log.d( TAG, "registerOnce(): now: %d; nextReg: %d", now, sNextReg ); + if ( now > sNextReg ) { + try { + JSONObject params = new JSONObject(); + params.put( "devid", mDevID ); + params.put( "gitrev", BuildConfig.GIT_REV ); + params.put( "os", Build.MODEL ); + params.put( "vers", Build.VERSION.RELEASE ); + params.put( "vrntCode", BuildConfig.VARIANT_CODE ); + params.put( "vrntName", BuildConfig.VARIANT_NAME ); + params.put( "myNow", now ); + + String fcmid = FBMService.getFCMDevID( mContext ); + if ( null != fcmid ) { + params.put( "fcmid", fcmid ); + } + + Log.d( TAG, "registerOnce(): sending %s", params ); + HttpsURLConnection conn + = NetUtils.makeHttpsMQTTConn( mContext, "register" ); + String resStr = NetUtils.runConn( conn, params, true ); + if ( null != resStr ) { + JSONObject response = new JSONObject( resStr ); + Log.d( TAG, "registerOnce(): got %s", response ); + + if ( response.optBoolean( "success", true ) ) { + long atNext = response.optLong( "atNext", 0 ); + if ( 0 < atNext ) { + DBUtils.setLongFor( mContext, KEY_NEXT_REG, atNext ); + sNextReg = atNext; + } + } + } else { + Log.e( TAG, "registerOnce(): null back from runConn()" ); + } + } catch ( JSONException je ) { + Log.e( TAG, "registerOnce() ex: %s", je ); + } + } } // private void setPaused( boolean paused ) @@ -279,6 +337,7 @@ public class MQTTUtils extends Thread implements IMqttActionListener, MqttCallba public static int send( Context context, String addressee, int gameID, byte[] buf ) { Log.d( TAG, "send(to:%s, len: %d)", addressee, buf.length ); + Assert.assertTrueNR( 16 == addressee.length() ); String[] topic = {addressee}; byte[] packet = XwJNI.dvc_makeMQTTMessage( gameID, buf, topic ); addToSendQueue( context, topic[0], packet ); @@ -388,6 +447,13 @@ public class MQTTUtils extends Thread implements IMqttActionListener, MqttCallba .postEvent( MultiService.MultiEvent.MESSAGE_NOGAME, gameID ); } + public static void fcmConfirmed( Context context, boolean working ) + { + if ( working ) { + DBUtils.setLongFor( context, KEY_NEXT_REG, 0 ); + } + } + private static class MQTTServiceHelper extends XWServiceHelper { private CommsAddrRec mReturnAddr; private Context mContext; diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/NetUtils.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/NetUtils.java index e4c6f718c..3f37ad620 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/NetUtils.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/NetUtils.java @@ -223,6 +223,14 @@ public class NetUtils { return makeHttpsConn( context, url, proc ); } + protected static HttpsURLConnection makeHttpsMQTTConn( Context context, + String proc ) + { + // String url = XWPrefs.getDefaultMQTTUrl( context ); + String url = "https://liquidsugar.net/xw4/api/v1"; + return makeHttpsConn( context, url, proc ); + } + protected static HttpsURLConnection makeHttpsUpdateConn( Context context, String proc ) { @@ -249,34 +257,47 @@ public class NetUtils { protected static String runConn( HttpsURLConnection conn, JSONArray param ) { - return runConn( conn, param.toString() ); + return runConn( conn, param.toString(), false ); } protected static String runConn( HttpsURLConnection conn, JSONObject param ) { - return runConn( conn, param.toString() ); + return runConn( conn, param.toString(), false ); } - private static String runConn( HttpsURLConnection conn, String param ) + protected static String runConn( HttpsURLConnection conn, JSONObject param, + boolean directJson ) + { + return runConn( conn, param.toString(), directJson ); + } + + private static String runConn( HttpsURLConnection conn, String param, + boolean directJson ) { String result = null; - Map params = new HashMap<>(); - params.put( k_PARAMS, param ); - String paramsString = getPostDataString( params ); + if ( ! directJson ) { + Map params = new HashMap<>(); + params.put( k_PARAMS, param ); + param = getPostDataString( params ); + } - if ( null != conn && null != paramsString ) { + if ( null != conn && null != param ) { try { conn.setReadTimeout( 15000 ); conn.setConnectTimeout( 15000 ); conn.setRequestMethod( "POST" ); + if ( directJson ) { + conn.setRequestProperty("Content-Type", "application/json;charset=UTF-8"); + } else { + conn.setFixedLengthStreamingMode( param.length() ); + } conn.setDoInput( true ); conn.setDoOutput( true ); - conn.setFixedLengthStreamingMode( paramsString.length() ); OutputStream os = conn.getOutputStream(); BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8")); - writer.write( paramsString ); + writer.write( param ); writer.flush(); writer.close(); os.close(); @@ -308,8 +329,7 @@ public class NetUtils { Log.ex( TAG, ioe ); } } else { - Log.e( TAG, "not running conn %s with params %s", conn, - paramsString ); + Log.e( TAG, "not running conn %s with params %s", conn, param ); } return result; diff --git a/xwords4/android/app/src/xw4NoSMS/java/org/eehouse/android/xw4/FBMService.java b/xwords4/android/app/src/xw4NoSMS/java/org/eehouse/android/xw4/FBMService.java index 5a9b2189c..13afe94a6 100644 --- a/xwords4/android/app/src/xw4NoSMS/java/org/eehouse/android/xw4/FBMService.java +++ b/xwords4/android/app/src/xw4NoSMS/java/org/eehouse/android/xw4/FBMService.java @@ -55,7 +55,7 @@ public class FBMService extends FirebaseMessagingService { if ( XWPrefs.getIgnoreFCM( this ) ) { Log.d( TAG, "onMessageReceived(): ignoring" ); } else { - RelayService.fcmConfirmed( this, true ); + callFcmConfirmed( this, true ); Map data = message.getData(); Log.d( TAG, "onMessageReceived(data=%s)", data ); @@ -137,7 +137,7 @@ public class FBMService extends FirebaseMessagingService { if (!task.isSuccessful()) { Log.w(TAG, "getInstanceId failed: %s", task.getException()); if ( !XWPrefs.getIgnoreFCM( context ) ) { - RelayService.fcmConfirmed( context, false ); + callFcmConfirmed( context, false ); } } else { @@ -160,6 +160,12 @@ public class FBMService extends FirebaseMessagingService { DBUtils.setStringFor( context, BuildConfig.KEY_FCMID, token ); DevID.setFCMDevID( context, token ); - RelayService.fcmConfirmed( context, true ); + callFcmConfirmed( context, true ); + } + + private static void callFcmConfirmed( Context context, boolean working ) + { + RelayService.fcmConfirmed( context, working ); + MQTTUtils.fcmConfirmed( context, working ); } }