diff --git a/xwords4/android/app/build.gradle b/xwords4/android/app/build.gradle
index 8b4f48134..d154eb972 100644
--- a/xwords4/android/app/build.gradle
+++ b/xwords4/android/app/build.gradle
@@ -22,12 +22,12 @@ def CURTAG = "git describe --exact-match".execute().text.trim()
apply plugin: 'com.android.application'
-if ( FABRIC_API_KEY && hasProperty('useCrashlytics') ) {
- apply plugin: 'io.fabric'
-}
+if ( FABRIC_API_KEY && hasProperty('useCrashlytics') ) { // rm-for-fdroid
+ apply plugin: 'io.fabric' // rm-for-fdroid
+} // rm-for-fdroid
repositories {
google()
- maven { url 'https://maven.fabric.io/public' }
+ maven { url 'https://maven.fabric.io/public' } // rm-for-fdroid
}
android {
@@ -210,9 +210,12 @@ dependencies {
// 2.6.8 is probably as far forward as I can go without upping my
// min-supported SDK version
- xw4dImplementation('com.crashlytics.sdk.android:crashlytics:2.6.3@aar') {
- transitive = true;
- }
+ xw4dImplementation('com.crashlytics.sdk.android:crashlytics:2.6.3@aar') { // rm-for-fdroid
+ transitive = true; // rm-for-fdroid
+ } // rm-for-fdroid
+
+ implementation 'com.google.firebase:firebase-messaging:17.3.4' // rm-for-fdroid
+ implementation 'com.google.firebase:firebase-core:16.0.6' // rm-for-fdroid
}
task mkImages(type: Exec) {
@@ -308,3 +311,5 @@ task makeBuildAssets() {
gradle.projectsEvaluated {
build.dependsOn(makeBuildAssets)
}
+
+apply plugin: 'com.google.gms.google-services' // rm-for-fdroid
diff --git a/xwords4/android/app/src/main/AndroidManifest.xml b/xwords4/android/app/src/main/AndroidManifest.xml
index ee6cecc8f..0e9e03dd0 100644
--- a/xwords4/android/app/src/main/AndroidManifest.xml
+++ b/xwords4/android/app/src/main/AndroidManifest.xml
@@ -228,5 +228,11 @@
+
+
+
+
+
+
diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DevID.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DevID.java
index 57af827cb..2b7b6db57 100644
--- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DevID.java
+++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DevID.java
@@ -35,8 +35,8 @@ public class DevID {
private static final String TAG = DevID.class.getSimpleName();
private static final String DEVID_KEY = "DevID.devid_key";
- private static final String DEVID_ACK_KEY = "key_relay_regid_ackd";
- private static final String GCM_REGVERS_KEY = "key_gcmvers_regid";
+ private static final String DEVID_ACK_KEY = "key_relay_regid_ackd2";
+ private static final String FCM_REGVERS_KEY = "key_fcmvers_regid";
private static String s_relayDevID;
private static int s_asInt;
@@ -111,10 +111,10 @@ public class DevID {
// DbgUtils.printStack();
}
- public static void setGCMDevID( Context context, String devID )
+ public static void setFCMDevID( Context context, String devID )
{
int curVers = Utils.getAppVersion( context );
- DBUtils.setIntFor( context, GCM_REGVERS_KEY, curVers );
+ DBUtils.setIntFor( context, FCM_REGVERS_KEY, curVers );
DBUtils.setBoolFor( context, DEVID_ACK_KEY, false );
}
diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/RelayService.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/RelayService.java
index 1ddf4052e..ec7961238 100644
--- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/RelayService.java
+++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/RelayService.java
@@ -28,11 +28,12 @@ import android.os.Handler;
import android.support.v4.app.JobIntentService;
import android.text.TextUtils;
+import org.eehouse.android.xw4.FBMService;
import org.eehouse.android.xw4.GameUtils.BackMoveResult;
import org.eehouse.android.xw4.MultiService.DictFetchOwner;
import org.eehouse.android.xw4.MultiService.MultiEvent;
-import org.eehouse.android.xw4.jni.CommsAddrRec;
import org.eehouse.android.xw4.jni.CommsAddrRec.CommsConnType;
+import org.eehouse.android.xw4.jni.CommsAddrRec;
import org.eehouse.android.xw4.jni.DUtilCtxt.DevIDType;
import org.eehouse.android.xw4.jni.XwJNI;
import org.eehouse.android.xw4.loc.LocUtils;
@@ -152,16 +153,16 @@ public class RelayService extends JobIntentService
XWPDEV_GOTINVITE, // test without this!!!
};
- public static void gcmConfirmed( Context context, boolean confirmed )
+ public static void fcmConfirmed( Context context, boolean working )
{
- if ( s_gcmWorking != confirmed ) {
- Log.i( TAG, "gcmConfirmed(): changing s_gcmWorking to %b",
- confirmed );
- s_gcmWorking = confirmed;
+ if ( s_gcmWorking != working ) {
+ Log.i( TAG, "fcmConfirmed(): changing s_gcmWorking to %b",
+ working );
+ s_gcmWorking = working;
}
// If we've gotten a GCM id and haven't registered it, do so!
- if ( confirmed && !s_curType.equals( DevIDType.ID_TYPE_ANDROID_GCM ) ) {
+ if ( working && !s_curType.equals( DevIDType.ID_TYPE_ANDROID_FCM ) ) {
s_regStartTime = 0; // so we're sure to register
devIDChanged();
timerFired( context );
@@ -732,7 +733,7 @@ public class RelayService extends JobIntentService
long now = Utils.getCurSeconds();
long interval = now - s_regStartTime;
if ( interval < REG_WAIT_INTERVAL ) {
- Log.i( TAG, "registerWithRelay: skipping because only %d "
+ Log.i( TAG, "registerWithRelay(): skipping because only %d "
+ "seconds since last start", interval );
} else {
String relayID = DevID.getRelayDevID( this );
@@ -920,9 +921,9 @@ public class RelayService extends JobIntentService
if ( null != devid && 0 < devid.length() ) {
typ = DevIDType.ID_TYPE_RELAY;
} else {
- devid = DevID.getGCMDevID( this );
+ devid = FBMService.getFCMDevID( this );
if ( null != devid && 0 < devid.length() ) {
- typ = DevIDType.ID_TYPE_ANDROID_GCM;
+ typ = DevIDType.ID_TYPE_ANDROID_FCM;
} else {
devid = "";
typ = DevIDType.ID_TYPE_ANON;
@@ -1624,7 +1625,7 @@ public class RelayService extends JobIntentService
private boolean shouldMaintainConnection()
{
boolean result = relayEnabled( this )
- && (!s_gcmWorking || XWPrefs.getIgnoreGCM( this ));
+ && (!s_gcmWorking || XWPrefs.getIgnoreFCM( this ));
if ( result ) {
long interval = Utils.getCurSeconds() - m_lastGamePacketReceived;
diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/XWApp.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/XWApp.java
index 08032b392..3bb5d2cfd 100644
--- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/XWApp.java
+++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/XWApp.java
@@ -90,6 +90,7 @@ public class XWApp extends Application implements LifecycleObserver {
UpdateCheckReceiver.restartTimer( this );
RelayService.startService( this );
+ FBMService.init( this );
WiDirWrapper.init( this );
}
diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/XWPrefs.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/XWPrefs.java
index 55ba5abfe..6011a22b7 100644
--- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/XWPrefs.java
+++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/XWPrefs.java
@@ -66,14 +66,14 @@ public class XWPrefs {
return getPrefsBoolean( context, R.string.key_enable_nfc_toself, false );
}
- public static boolean getIgnoreGCM( Context context )
+ public static boolean getIgnoreFCM( Context context )
{
- return getPrefsBoolean( context, R.string.key_ignore_gcm, false );
+ return getPrefsBoolean( context, R.string.key_ignore_fcm, false );
}
- public static boolean getToastGCM( Context context )
+ public static boolean getToastFCM( Context context )
{
- return getPrefsBoolean( context, R.string.key_show_gcm, false );
+ return getPrefsBoolean( context, R.string.key_show_fcm, false );
}
public static boolean getSMSToSelfEnabled( Context context )
diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/DUtilCtxt.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/DUtilCtxt.java
index ae13ba97d..f6edff479 100644
--- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/DUtilCtxt.java
+++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/DUtilCtxt.java
@@ -24,11 +24,12 @@ import android.content.Context;
import android.telephony.PhoneNumberUtils;
import org.eehouse.android.xw4.Assert;
-import org.eehouse.android.xw4.XWApp;
import org.eehouse.android.xw4.DBUtils;
import org.eehouse.android.xw4.DevID;
-import org.eehouse.android.xw4.R;
+import org.eehouse.android.xw4.FBMService;
import org.eehouse.android.xw4.Log;
+import org.eehouse.android.xw4.R;
+import org.eehouse.android.xw4.XWApp;
import org.eehouse.android.xw4.loc.LocUtils;
public class DUtilCtxt {
@@ -40,13 +41,14 @@ public class DUtilCtxt {
m_context = XWApp.getContext();
}
- // Possible values for typ[0], these must match enum in xwrelay.sh
+ // Possible values for typ[0], these must match enum in xwrelay.h
public enum DevIDType { ID_TYPE_NONE
- , ID_TYPE_RELAY
- , ID_TYPE_LINUX
- , ID_TYPE_ANDROID_GCM
- , ID_TYPE_ANDROID_OTHER
- , ID_TYPE_ANON
+ , ID_TYPE_RELAY
+ , ID_TYPE_LINUX
+ , ID_TYPE_ANDROID_GCM_UNUSED // 3
+ , ID_TYPE_ANDROID_OTHER
+ , ID_TYPE_ANON
+ , ID_TYPE_ANDROID_FCM // 6
}
public String getDevID( /*out*/ byte[] typa )
@@ -56,11 +58,11 @@ public class DUtilCtxt {
if ( null != result ) {
typ = DevIDType.ID_TYPE_RELAY;
} else {
- result = DevID.getGCMDevID( m_context );
+ result = FBMService.getFCMDevID( m_context );
if ( result.equals("") ) {
result = null;
} else {
- typ = DevIDType.ID_TYPE_ANDROID_GCM;
+ typ = DevIDType.ID_TYPE_ANDROID_FCM;
}
}
typa[0] = (byte)typ.ordinal();
diff --git a/xwords4/android/app/src/main/res/values/common_rsrc.xml b/xwords4/android/app/src/main/res/values/common_rsrc.xml
index e5e1e255f..419decc77 100644
--- a/xwords4/android/app/src/main/res/values/common_rsrc.xml
+++ b/xwords4/android/app/src/main/res/values/common_rsrc.xml
@@ -126,8 +126,8 @@
key_enable_nfc_toself
key_enable_sms_toself
key_enable_smsproto
- key_ignore_gcm
- key_show_gcm
+ key_ignore_fcm
+ key_show_fcm
key_nag_intervals
key_download_path
key_got_langdict
diff --git a/xwords4/android/app/src/main/res/values/strings.xml b/xwords4/android/app/src/main/res/values/strings.xml
index 969706af1..ad3927a32 100644
--- a/xwords4/android/app/src/main/res/values/strings.xml
+++ b/xwords4/android/app/src/main/res/values/strings.xml
@@ -2639,11 +2639,11 @@
devices and I think it\'s rare that people play with more than
two. Let me know if I\'m wrong and I\'ll up the priority.
- Ignore incoming GCM messages
- Mimic life without a google account
+ Ignore incoming FCM messages
+ Mimic life without a google account
Show SMS sends, receives
- Show GCM receives
+ Show FCM receives
diff --git a/xwords4/android/app/src/main/res/xml/xwprefs.xml b/xwords4/android/app/src/main/res/xml/xwprefs.xml
index 8d6204d6d..9045fe6b5 100644
--- a/xwords4/android/app/src/main/res/xml/xwprefs.xml
+++ b/xwords4/android/app/src/main/res/xml/xwprefs.xml
@@ -393,13 +393,13 @@
-
-
data = message.getData();
+ Log.d( TAG, "onMessageReceived(data=%s)", data );
+ boolean toastFCM = XWPrefs.getToastFCM( this );
+
+ String value = data.get( "msgs64" );
+ if ( null != value ) {
+ String connname = data.get( "connname" );
+ try {
+ JSONArray msgs64 = new JSONArray( value );
+ String[] strs64 = new String[msgs64.length()];
+ if ( toastFCM ) {
+ DbgUtils.showf( this, "onMessage(): got %d msgs",
+ strs64.length );
+ }
+
+ for ( int ii = 0; ii < strs64.length; ++ii ) {
+ strs64[ii] = msgs64.optString(ii);
+ }
+ if ( null == connname ) {
+ RelayService.processDevMsgs( this, strs64 );
+ } else {
+ RelayService.processGameMsgs( this, connname, strs64 );
+ }
+ } catch (org.json.JSONException jse ) {
+ Log.ex( TAG, jse );
+ Assert.assertFalse( BuildConfig.DEBUG );
+ }
+ }
+
+ value = data.get( "checkUpdates" );
+ if ( null != value && Boolean.parseBoolean( value ) ) {
+ UpdateCheckReceiver.checkVersions( this, true );
+ }
+
+ value = data.get( "getMoves" );
+ if ( null != value && Boolean.parseBoolean( value ) ) {
+ RelayService.timerFired( this );
+ if ( toastFCM ) {
+ DbgUtils.showf( this, "onMessage(): got 'getMoves'" );
+ }
+ }
+
+ value = data.get( "msg" );
+ if ( null != value ) {
+ String title = data.get( "title" );
+ if ( null != title ) {
+ String teaser = data.get( "teaser" );
+ if ( null == teaser ) {
+ teaser = value;
+ }
+ Intent alertIntent = GamesListDelegate
+ .makeAlertIntent( this, value );
+ int code = value.hashCode() ^ title.hashCode();
+ Utils.postNotification( this, alertIntent, title,
+ teaser, code );
+ }
+ }
+ }
+ }
+
+ public static String getFCMDevID( Context context )
+ {
+ String result = DBUtils.getStringFor( context, KEY_FCMID, null );
+
+ if ( null == result ) {
+ getTokenAsync( context );
+ }
+
+ Log.d( TAG, "getFCMDevID() => %s", result );
+ return result;
+ }
+
+ private static void getTokenAsync( final Context context )
+ {
+ FirebaseInstanceId.getInstance().getInstanceId()
+ .addOnCompleteListener(new OnCompleteListener() {
+ @Override
+ public void onComplete(Task task) {
+ if (!task.isSuccessful()) {
+ Log.w(TAG, "getInstanceId failed: %s", task.getException());
+ if ( !XWPrefs.getIgnoreFCM( context ) ) {
+ RelayService.fcmConfirmed( context, false );
+ }
+ } else {
+
+ // Get new Instance ID token
+ String token = task.getResult().getToken();
+
+ // Log and toast
+ Log.d(TAG, "got token!: %s", token );
+ onGotToken( context, token );
+ }
+ }
+ });
+ }
+
+ private static void onGotToken( Context context, String token )
+ {
+ // Don't call this with empty tokens!!!
+ Assert.assertTrue( token.length() > 0 || !BuildConfig.DEBUG );
+
+ DBUtils.setStringFor( context, KEY_FCMID, token );
+ DevID.setFCMDevID( context, token );
+
+ if ( !XWPrefs.getIgnoreFCM( context ) ) {
+ RelayService.fcmConfirmed( context, true );
+ }
+ }
+}
diff --git a/xwords4/android/app/src/xw4d/google-services.json b/xwords4/android/app/src/xw4d/google-services.json
new file mode 100644
index 000000000..d1552e7ec
--- /dev/null
+++ b/xwords4/android/app/src/xw4d/google-services.json
@@ -0,0 +1,73 @@
+{
+ "project_info": {
+ "project_number": "801272813571",
+ "firebase_url": "https://fcmtest-9fe99.firebaseio.com",
+ "project_id": "fcmtest-9fe99",
+ "storage_bucket": "fcmtest-9fe99.appspot.com"
+ },
+ "client": [
+ {
+ "client_info": {
+ "mobilesdk_app_id": "1:801272813571:android:15f4eb80a9b07720",
+ "android_client_info": {
+ "package_name": "com.google.firebase.fiamquickstart"
+ }
+ },
+ "oauth_client": [
+ {
+ "client_id": "801272813571-g3lfciu89q8ffb7ahasrce5nj3vsghot.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ],
+ "api_key": [
+ {
+ "current_key": "AIzaSyCl3lfUITEX0EscF2aeDZY4G-DNL2xeEZ8"
+ }
+ ],
+ "services": {
+ "analytics_service": {
+ "status": 1
+ },
+ "appinvite_service": {
+ "status": 1,
+ "other_platform_oauth_client": []
+ },
+ "ads_service": {
+ "status": 2
+ }
+ }
+ },
+ {
+ "client_info": {
+ "mobilesdk_app_id": "1:801272813571:android:8c4ed916336414b2",
+ "android_client_info": {
+ "package_name": "org.eehouse.android.xw4dbg"
+ }
+ },
+ "oauth_client": [
+ {
+ "client_id": "801272813571-g3lfciu89q8ffb7ahasrce5nj3vsghot.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ],
+ "api_key": [
+ {
+ "current_key": "AIzaSyCl3lfUITEX0EscF2aeDZY4G-DNL2xeEZ8"
+ }
+ ],
+ "services": {
+ "analytics_service": {
+ "status": 1
+ },
+ "appinvite_service": {
+ "status": 1,
+ "other_platform_oauth_client": []
+ },
+ "ads_service": {
+ "status": 2
+ }
+ }
+ }
+ ],
+ "configuration_version": "1"
+}
\ No newline at end of file
diff --git a/xwords4/android/app/src/xw4d/java/org/eehouse/android/xw4/FBMService.java b/xwords4/android/app/src/xw4d/java/org/eehouse/android/xw4/FBMService.java
new file mode 120000
index 000000000..c61b45e58
--- /dev/null
+++ b/xwords4/android/app/src/xw4d/java/org/eehouse/android/xw4/FBMService.java
@@ -0,0 +1 @@
+../../../../../../xw4/java/org/eehouse/android/xw4/FBMService.java
\ No newline at end of file
diff --git a/xwords4/android/app/src/xw4fdroid/java/org/eehouse/android/xw4/FBMService.java b/xwords4/android/app/src/xw4fdroid/java/org/eehouse/android/xw4/FBMService.java
new file mode 100644
index 000000000..4545cfb29
--- /dev/null
+++ b/xwords4/android/app/src/xw4fdroid/java/org/eehouse/android/xw4/FBMService.java
@@ -0,0 +1,39 @@
+/* -*- compile-command: "find-and-gradle.sh -PuseCrashlytics insXw4dDeb"; -*- */
+/*
+ * Copyright 2019 by Eric House (xwords@eehouse.org). All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package org.eehouse.android.xw4;
+
+import android.content.Context;
+import android.content.Intent;
+
+public class FBMService {
+ private static final String TAG = FBMService.class.getSimpleName();
+ private static final String KEY_FCMID = TAG + "_fcmid";
+
+ public static void init( Context context )
+ {
+ Log.d( TAG, "init()" );
+ RelayService.fcmConfirmed( context, false );
+ }
+
+ public static String getFCMDevID( Context context )
+ {
+ return null;
+ }
+}
diff --git a/xwords4/android/build.gradle b/xwords4/android/build.gradle
index 85b486c88..d440e7b7f 100644
--- a/xwords4/android/build.gradle
+++ b/xwords4/android/build.gradle
@@ -4,12 +4,13 @@ buildscript {
repositories {
google()
jcenter()
- maven { url 'https://maven.fabric.io/public' }
+ maven { url 'https://maven.fabric.io/public' } // rm-for-fdroid
}
dependencies {
classpath 'com.android.tools.build:gradle:3.1.2'
- classpath 'io.fabric.tools:gradle:1.+'
+ classpath 'io.fabric.tools:gradle:1.+' // rm-for-fdroid
+ classpath 'com.google.gms:google-services:4.2.0' // google-services plugin
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
diff --git a/xwords4/relay/xwrelay.h b/xwords4/relay/xwrelay.h
index a502957c0..cb547ce5a 100644
--- a/xwords4/relay/xwrelay.h
+++ b/xwords4/relay/xwrelay.h
@@ -206,6 +206,7 @@ typedef enum {
,ID_TYPE_ANDROID_GCM
,ID_TYPE_ANDROID_OTHER
,ID_TYPE_ANON /* please assign me one based on nothing */
+ ,ID_TYPE_ANDROID_FCM
,ID_TYPE_NTYPES
} DevIDType;