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;