diff options
Diffstat (limited to 'StoneIsland/plugins/phonegap-plugin-push/src')
14 files changed, 344 insertions, 701 deletions
diff --git a/StoneIsland/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/BackgroundActionButtonHandler.java b/StoneIsland/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/BackgroundActionButtonHandler.java index 4456f525..3ccea6cb 100644 --- a/StoneIsland/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/BackgroundActionButtonHandler.java +++ b/StoneIsland/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/BackgroundActionButtonHandler.java @@ -9,7 +9,7 @@ import android.util.Log; import android.support.v4.app.RemoteInput; public class BackgroundActionButtonHandler extends BroadcastReceiver implements PushConstants { - private static String LOG_TAG = "Push_BGActionButton"; + private static String LOG_TAG = "PushPlugin_BackgroundActionButtonHandler"; @Override public void onReceive(Context context, Intent intent) { @@ -19,7 +19,7 @@ public class BackgroundActionButtonHandler extends BroadcastReceiver implements int notId = intent.getIntExtra(NOT_ID, 0); Log.d(LOG_TAG, "not id = " + notId); NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); - notificationManager.cancel(FCMService.getAppName(context), notId); + notificationManager.cancel(GCMIntentService.getAppName(context), notId); if (extras != null) { Bundle originalExtras = extras.getBundle(PUSH_BUNDLE); diff --git a/StoneIsland/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/FCMService.java b/StoneIsland/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/GCMIntentService.java index af328fb2..e1a2b75c 100644 --- a/StoneIsland/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/FCMService.java +++ b/StoneIsland/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/GCMIntentService.java @@ -13,23 +13,17 @@ import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Color; -import android.graphics.PorterDuff; -import android.graphics.PorterDuffXfermode; -import android.graphics.Rect; -import android.graphics.RectF; -import android.graphics.Paint; -import android.graphics.Canvas; import android.net.Uri; import android.os.Bundle; import android.support.v4.app.NotificationCompat; +import android.support.v4.app.NotificationManagerCompat; import android.support.v4.app.NotificationCompat.WearableExtender; import android.support.v4.app.RemoteInput; import android.text.Html; import android.text.Spanned; import android.util.Log; -import com.google.firebase.messaging.FirebaseMessagingService; -import com.google.firebase.messaging.RemoteMessage; +import com.google.android.gms.gcm.GcmListenerService; import org.json.JSONArray; import org.json.JSONException; @@ -42,13 +36,12 @@ import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; -import java.util.Map; import java.util.Random; @SuppressLint("NewApi") -public class FCMService extends FirebaseMessagingService implements PushConstants { +public class GCMIntentService extends GcmListenerService implements PushConstants { - private static final String LOG_TAG = "Push_FCMService"; + private static final String LOG_TAG = "PushPlugin_GCMIntentService"; private static HashMap<Integer, ArrayList<String>> messageMap = new HashMap<Integer, ArrayList<String>>(); public void setNotification(int notId, String message){ @@ -66,31 +59,17 @@ public class FCMService extends FirebaseMessagingService implements PushConstant } @Override - public void onMessageReceived(RemoteMessage message){ - - String from = message.getFrom(); + public void onMessageReceived(String from, Bundle extras) { Log.d(LOG_TAG, "onMessage - from: " + from); - Bundle extras = new Bundle(); - - if (message.getNotification()!=null) { - extras.putString(TITLE,message.getNotification().getTitle()); - extras.putString(MESSAGE,message.getNotification().getBody()); - } - for (Map.Entry<String, String> entry : message.getData().entrySet()) { - extras.putString(entry.getKey(), entry.getValue()); - } - - if (extras != null && isAvailableSender(from)) { + if (extras != null) { Context applicationContext = getApplicationContext(); SharedPreferences prefs = applicationContext.getSharedPreferences(PushPlugin.COM_ADOBE_PHONEGAP_PUSH, Context.MODE_PRIVATE); boolean forceShow = prefs.getBoolean(FORCE_SHOW, false); boolean clearBadge = prefs.getBoolean(CLEAR_BADGE, false); - String messageKey = prefs.getString(MESSAGE_KEY, MESSAGE); - String titleKey = prefs.getString(TITLE_KEY, TITLE); - extras = normalizeExtras(applicationContext, extras, messageKey, titleKey); + extras = normalizeExtras(applicationContext, extras); if (clearBadge) { PushPlugin.setApplicationIconBadgeNumber(getApplicationContext(), 0); @@ -188,10 +167,10 @@ public class FCMService extends FirebaseMessagingService implements PushConstant /* * Replace alternate keys with our canonical value */ - private String normalizeKey(String key, String messageKey, String titleKey) { - if (key.equals(BODY) || key.equals(ALERT) || key.equals(MP_MESSAGE) || key.equals(GCM_NOTIFICATION_BODY) || key.equals(TWILIO_BODY) || key.equals(messageKey)) { + private String normalizeKey(String key) { + if (key.equals(BODY) || key.equals(ALERT) || key.equals(GCM_NOTIFICATION_BODY) || key.equals(TWILIO_BODY)) { return MESSAGE; - } else if (key.equals(TWILIO_TITLE) || key.equals(SUBJECT) || key.equals(titleKey)) { + } else if (key.equals(TWILIO_TITLE)) { return TITLE; }else if (key.equals(MSGCNT) || key.equals(BADGE)) { return COUNT; @@ -212,7 +191,7 @@ public class FCMService extends FirebaseMessagingService implements PushConstant /* * Parse bundle into normalized keys. */ - private Bundle normalizeExtras(Context context, Bundle extras, String messageKey, String titleKey) { + private Bundle normalizeExtras(Context context, Bundle extras) { Log.d(LOG_TAG, "normalize extras"); Iterator<String> it = extras.keySet().iterator(); Bundle newExtras = new Bundle(); @@ -224,7 +203,7 @@ public class FCMService extends FirebaseMessagingService implements PushConstant // If normalizeKeythe key is "data" or "message" and the value is a json object extract // This is to support parse.com and other services. Issue #147 and pull #218 - if (key.equals(PARSE_COM_DATA) || key.equals(MESSAGE) || key.equals(messageKey)) { + if (key.equals(PARSE_COM_DATA) || key.equals(MESSAGE)) { Object json = extras.get(key); // Make sure data is json object stringified if ( json instanceof String && ((String) json).startsWith("{") ) { @@ -232,8 +211,7 @@ public class FCMService extends FirebaseMessagingService implements PushConstant try { // If object contains message keys promote each value to the root of the bundle JSONObject data = new JSONObject((String) json); - if ( data.has(ALERT) || data.has(MESSAGE) || data.has(BODY) || data.has(TITLE) || - data.has(messageKey) || data.has(titleKey) ) { + if ( data.has(ALERT) || data.has(MESSAGE) || data.has(BODY) || data.has(TITLE) ) { Iterator<String> jsonIter = data.keys(); while (jsonIter.hasNext()) { String jsonKey = jsonIter.next(); @@ -241,7 +219,7 @@ public class FCMService extends FirebaseMessagingService implements PushConstant Log.d(LOG_TAG, "key = data/" + jsonKey); String value = data.getString(jsonKey); - jsonKey = normalizeKey(jsonKey, messageKey, titleKey); + jsonKey = normalizeKey(jsonKey); value = localizeKey(context, jsonKey, value); newExtras.putString(jsonKey, value); @@ -250,10 +228,6 @@ public class FCMService extends FirebaseMessagingService implements PushConstant } catch( JSONException e) { Log.e(LOG_TAG, "normalizeExtras: JSON exception"); } - } else { - String newKey = normalizeKey(key, messageKey, titleKey); - Log.d(LOG_TAG, "replace key " + key + " with " + newKey); - replaceKey(context, key, newKey, extras, newExtras); } } else if (key.equals(("notification"))) { Bundle value = extras.getBundle(key); @@ -262,7 +236,7 @@ public class FCMService extends FirebaseMessagingService implements PushConstant String notifkey = iterator.next(); Log.d(LOG_TAG, "notifkey = " + notifkey); - String newKey = normalizeKey(notifkey, messageKey, titleKey); + String newKey = normalizeKey(notifkey); Log.d(LOG_TAG, "replace key " + notifkey + " with " + newKey); String valueData = value.getString(notifkey); @@ -271,17 +245,12 @@ public class FCMService extends FirebaseMessagingService implements PushConstant newExtras.putString(newKey, valueData); } continue; - // In case we weren't working on the payload data node or the notification node, - // normalize the key. - // This allows to have "message" as the payload data key without colliding - // with the other "message" key (holding the body of the payload) - // See issue #1663 - } else { - String newKey = normalizeKey(key, messageKey, titleKey); - Log.d(LOG_TAG, "replace key " + key + " with " + newKey); - replaceKey(context, key, newKey, extras, newExtras); } + String newKey = normalizeKey(key); + Log.d(LOG_TAG, "replace key " + key + " with " + newKey); + replaceKey(context, key, newKey, extras, newExtras); + } // while return newExtras; @@ -332,15 +301,15 @@ public class FCMService extends FirebaseMessagingService implements PushConstant createNotification(context, extras); } - if(!PushPlugin.isActive() && "1".equals(forceStart)){ + if(!PushPlugin.isActive() && "1".equals(forceStart)){ Log.d(LOG_TAG, "app is not running but we should start it and put in background"); - Intent intent = new Intent(this, PushHandlerActivity.class); + Intent intent = new Intent(this, PushHandlerActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.putExtra(PUSH_BUNDLE, extras); - intent.putExtra(START_IN_BACKGROUND, true); + intent.putExtra(START_IN_BACKGROUND, true); intent.putExtra(FOREGROUND, false); startActivity(intent); - } else if ("1".equals(contentAvailable)) { + } else if ("1".equals(contentAvailable)) { Log.d(LOG_TAG, "app is not running and content available true"); Log.d(LOG_TAG, "send notification event"); PushPlugin.sendExtras(extras); @@ -362,22 +331,12 @@ public class FCMService extends FirebaseMessagingService implements PushConstant int requestCode = new Random().nextInt(); PendingIntent contentIntent = PendingIntent.getActivity(this, requestCode, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); - Intent dismissedNotificationIntent = new Intent(this, PushDismissedHandler.class); - dismissedNotificationIntent.putExtra(PUSH_BUNDLE, extras); - dismissedNotificationIntent.putExtra(NOT_ID, notId); - dismissedNotificationIntent.putExtra(DISMISSED, true); - dismissedNotificationIntent.setAction(PUSH_DISMISSED); - - requestCode = new Random().nextInt(); - PendingIntent deleteIntent = PendingIntent.getBroadcast(this, requestCode, dismissedNotificationIntent, PendingIntent.FLAG_CANCEL_CURRENT); - NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context) .setWhen(System.currentTimeMillis()) .setContentTitle(fromHtml(extras.getString(TITLE))) .setTicker(fromHtml(extras.getString(TITLE))) .setContentIntent(contentIntent) - .setDeleteIntent(deleteIntent) .setAutoCancel(true); SharedPreferences prefs = context.getSharedPreferences(PushPlugin.COM_ADOBE_PHONEGAP_PUSH, Context.MODE_PRIVATE); @@ -731,46 +690,11 @@ public class FCMService extends FirebaseMessagingService implements PushConstant } } - private Bitmap getCircleBitmap(Bitmap bitmap) { - if (bitmap == null) { - return null; - } - - final Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888); - final Canvas canvas = new Canvas(output); - final int color = Color.RED; - final Paint paint = new Paint(); - final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); - final RectF rectF = new RectF(rect); - - paint.setAntiAlias(true); - canvas.drawARGB(0, 0, 0, 0); - paint.setColor(color); - float cx = bitmap.getWidth()/2; - float cy = bitmap.getHeight()/2; - float radius = cx < cy ? cx : cy; - canvas.drawCircle(cx,cy,radius,paint); - - paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); - canvas.drawBitmap(bitmap, rect, rect, paint); - - bitmap.recycle(); - - return output; - } - private void setNotificationLargeIcon(Bundle extras, String packageName, Resources resources, NotificationCompat.Builder mBuilder) { String gcmLargeIcon = extras.getString(IMAGE); // from gcm - String imageType = extras.getString(IMAGE_TYPE, IMAGE_TYPE_SQUARE); if (gcmLargeIcon != null && !"".equals(gcmLargeIcon)) { if (gcmLargeIcon.startsWith("http://") || gcmLargeIcon.startsWith("https://")) { - Bitmap bitmap = getBitmapFromURL(gcmLargeIcon); - if (IMAGE_TYPE_SQUARE.equalsIgnoreCase(imageType)) { - mBuilder.setLargeIcon(bitmap); - } else { - Bitmap bm = getCircleBitmap(bitmap); - mBuilder.setLargeIcon(bm); - } + mBuilder.setLargeIcon(getBitmapFromURL(gcmLargeIcon)); Log.d(LOG_TAG, "using remote large-icon from gcm"); } else { AssetManager assetManager = getAssets(); @@ -778,12 +702,7 @@ public class FCMService extends FirebaseMessagingService implements PushConstant try { istr = assetManager.open(gcmLargeIcon); Bitmap bitmap = BitmapFactory.decodeStream(istr); - if (IMAGE_TYPE_SQUARE.equalsIgnoreCase(imageType)) { - mBuilder.setLargeIcon(bitmap); - } else { - Bitmap bm = getCircleBitmap(bitmap); - mBuilder.setLargeIcon(bm); - } + mBuilder.setLargeIcon(bitmap); Log.d(LOG_TAG, "using assets large-icon from gcm"); } catch (IOException e) { int largeIconId = 0; @@ -843,7 +762,6 @@ public class FCMService extends FirebaseMessagingService implements PushConstant try { URL url = new URL(strURL); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - connection.setConnectTimeout(15000); connection.setDoInput(true); connection.connect(); InputStream input = connection.getInputStream(); @@ -881,11 +799,4 @@ public class FCMService extends FirebaseMessagingService implements PushConstant else return null; } - - private boolean isAvailableSender(String from) { - SharedPreferences sharedPref = getApplicationContext().getSharedPreferences(PushPlugin.COM_ADOBE_PHONEGAP_PUSH, Context.MODE_PRIVATE); - String savedSenderID = sharedPref.getString(SENDER_ID, ""); - - return from.equals(savedSenderID) || from.startsWith("/topics/"); - } } diff --git a/StoneIsland/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/PermissionUtils.java b/StoneIsland/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/PermissionUtils.java index 41bc6a6f..6aa5c9bf 100644 --- a/StoneIsland/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/PermissionUtils.java +++ b/StoneIsland/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/PermissionUtils.java @@ -10,12 +10,8 @@ import java.lang.reflect.Method; public class PermissionUtils { private static final String CHECK_OP_NO_THROW = "checkOpNoThrow"; - private static final int MIN_API_LEVEL = 19; // required by AppOpsManager public static boolean hasPermission(Context appContext, String appOpsServiceId) throws UnknownError { - if (android.os.Build.VERSION.SDK_INT < MIN_API_LEVEL) { - return true; - } ApplicationInfo appInfo = appContext.getApplicationInfo(); diff --git a/StoneIsland/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/PushConstants.java b/StoneIsland/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/PushConstants.java index e3aa217c..37874e04 100644 --- a/StoneIsland/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/PushConstants.java +++ b/StoneIsland/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/PushConstants.java @@ -3,7 +3,6 @@ package com.adobe.phonegap.push; public interface PushConstants { public static final String COM_ADOBE_PHONEGAP_PUSH = "com.adobe.phonegap.push"; public static final String REGISTRATION_ID = "registrationId"; - public static final String REGISTRATION_TYPE = "registrationType"; public static final String FOREGROUND = "foreground"; public static final String TITLE = "title"; public static final String NOT_ID = "notId"; @@ -56,11 +55,10 @@ public interface PushConstants { public static final String FROM = "from"; public static final String COLLAPSE_KEY = "collapse_key"; public static final String FORCE_SHOW = "forceShow"; - public static final String FCM = "FCM"; + public static final String GCM = "GCM"; public static final String CONTENT_AVAILABLE = "content-available"; public static final String TOPICS = "topics"; public static final String SET_APPLICATION_ICON_BADGE_NUMBER = "setApplicationIconBadgeNumber"; - public static final String GET_APPLICATION_ICON_BADGE_NUMBER = "getApplicationIconBadgeNumber"; public static final String CLEAR_ALL_NOTIFICATIONS = "clearAllNotifications"; public static final String VISIBILITY = "visibility"; public static final String INLINE_REPLY = "inlineReply"; @@ -69,18 +67,6 @@ public interface PushConstants { public static final String TWILIO_BODY = "twi_body"; public static final String TWILIO_TITLE = "twi_title"; public static final String TWILIO_SOUND = "twi_sound"; - public static final String MP_MESSAGE = "mp_message"; public static final String START_IN_BACKGROUND = "cdvStartInBackground"; public static final String FORCE_START = "force-start"; - public static final String MESSAGE_KEY = "messageKey"; - public static final String TITLE_KEY = "titleKey"; - public static final String NO_CACHE = "no-cache"; - public static final String DISMISSED = "dismissed"; - public static final String IMAGE_TYPE = "image-type"; - public static final String IMAGE_TYPE_SQUARE = "square"; - public static final String IMAGE_TYPE_CIRCLE = "circle"; - public static final String SUBJECT = "subject"; - public static final String GOOGLE_APP_ID = "google_app_id"; - public static final String GCM_DEFAULT_SENDER_ID = "gcm_defaultSenderId"; - public static final String PUSH_DISMISSED = "push_dismissed"; } diff --git a/StoneIsland/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/PushDismissedHandler.java b/StoneIsland/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/PushDismissedHandler.java deleted file mode 100644 index a517bc1e..00000000 --- a/StoneIsland/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/PushDismissedHandler.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.adobe.phonegap.push; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.os.Bundle; -import android.util.Log; - -public class PushDismissedHandler extends BroadcastReceiver implements PushConstants { - private static String LOG_TAG = "Push_DismissedHandler"; - - @Override - public void onReceive(Context context, Intent intent) { - Bundle extras = intent.getExtras(); - FCMService fcm = new FCMService(); - String action = intent.getAction(); - int notID = intent.getIntExtra(NOT_ID, 0); - - if (action.equals(PUSH_DISMISSED)) { - Log.d(LOG_TAG, "PushDismissedHandler = " + extras); - Log.d(LOG_TAG, "not id = " + notID); - - fcm.setNotification(notID, ""); - } - } -} diff --git a/StoneIsland/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/PushHandlerActivity.java b/StoneIsland/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/PushHandlerActivity.java index 0d399a61..23682ac8 100644 --- a/StoneIsland/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/PushHandlerActivity.java +++ b/StoneIsland/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/PushHandlerActivity.java @@ -11,7 +11,7 @@ import android.support.v4.app.RemoteInput; public class PushHandlerActivity extends Activity implements PushConstants { - private static String LOG_TAG = "Push_HandlerActivity"; + private static String LOG_TAG = "PushPlugin_PushHandlerActivity"; /* * this activity will be started if the user touches a notification that we own. @@ -21,7 +21,7 @@ public class PushHandlerActivity extends Activity implements PushConstants { */ @Override public void onCreate(Bundle savedInstanceState) { - FCMService gcm = new FCMService(); + GCMIntentService gcm = new GCMIntentService(); Intent intent = getIntent(); @@ -34,18 +34,16 @@ public class PushHandlerActivity extends Activity implements PushConstants { Log.d(LOG_TAG, "callback = " + callback); boolean foreground = getIntent().getExtras().getBoolean("foreground", true); boolean startOnBackground = getIntent().getExtras().getBoolean(START_IN_BACKGROUND, false); - boolean dismissed = getIntent().getExtras().getBoolean(DISMISSED, false); - Log.d(LOG_TAG, "dismissed = " + dismissed); if(!startOnBackground){ NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); - notificationManager.cancel(FCMService.getAppName(this), notId); + notificationManager.cancel(GCMIntentService.getAppName(this), notId); } boolean isPushPluginActive = PushPlugin.isActive(); boolean inline = processPushBundle(isPushPluginActive, intent); - if(inline && android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.N && !startOnBackground){ + if(inline && android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.N){ foreground = true; } @@ -53,17 +51,15 @@ public class PushHandlerActivity extends Activity implements PushConstants { finish(); - if(!dismissed) { - Log.d(LOG_TAG, "isPushPluginActive = " + isPushPluginActive); - if (!isPushPluginActive && foreground && inline) { - Log.d(LOG_TAG, "forceMainActivityReload"); - forceMainActivityReload(false); - } else if(startOnBackground) { - Log.d(LOG_TAG, "startOnBackgroundTrue"); - forceMainActivityReload(true); - } else { - Log.d(LOG_TAG, "don't want main activity"); - } + Log.d(LOG_TAG, "isPushPluginActive = " + isPushPluginActive); + if (!isPushPluginActive && foreground && inline) { + Log.d(LOG_TAG, "forceMainActivityReload"); + forceMainActivityReload(false); + } else if(startOnBackground) { + Log.d(LOG_TAG, "startOnBackgroundTrue"); + forceMainActivityReload(true); + } else { + Log.d(LOG_TAG, "don't want main activity"); } } @@ -80,9 +76,7 @@ public class PushHandlerActivity extends Activity implements PushConstants { originalExtras.putBoolean(FOREGROUND, false); originalExtras.putBoolean(COLDSTART, !isPushPluginActive); - originalExtras.putBoolean(DISMISSED, extras.getBoolean(DISMISSED)); originalExtras.putString(ACTION_CALLBACK, extras.getString(CALLBACK)); - originalExtras.remove(NO_CACHE); remoteInput = RemoteInput.getResultsFromIntent(intent); if (remoteInput != null) { diff --git a/StoneIsland/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/PushInstanceIDListenerService.java b/StoneIsland/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/PushInstanceIDListenerService.java index 176b7419..eaa39a48 100644 --- a/StoneIsland/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/PushInstanceIDListenerService.java +++ b/StoneIsland/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/PushInstanceIDListenerService.java @@ -5,22 +5,23 @@ import android.content.Context; import android.content.SharedPreferences; import android.util.Log; -import com.google.firebase.iid.FirebaseInstanceId; -import com.google.firebase.iid.FirebaseInstanceIdService; +import com.google.android.gms.iid.InstanceID; +import com.google.android.gms.iid.InstanceIDListenerService; import org.json.JSONException; import java.io.IOException; -public class PushInstanceIDListenerService extends FirebaseInstanceIdService implements PushConstants { - public static final String LOG_TAG = "Push_InsIdService"; +public class PushInstanceIDListenerService extends InstanceIDListenerService implements PushConstants { + public static final String LOG_TAG = "PushPlugin_PushInstanceIDListenerService"; @Override public void onTokenRefresh() { - // Get updated InstanceID token. - String refreshedToken = FirebaseInstanceId.getInstance().getToken(); - Log.d(LOG_TAG, "Refreshed token: " + refreshedToken); - // TODO: Implement this method to send any registration to your app's servers. - //sendRegistrationToServer(refreshedToken); + SharedPreferences sharedPref = getApplicationContext().getSharedPreferences(COM_ADOBE_PHONEGAP_PUSH, Context.MODE_PRIVATE); + String senderID = sharedPref.getString(SENDER_ID, ""); + if (!"".equals(senderID)) { + Intent intent = new Intent(this, RegistrationIntentService.class); + startService(intent); + } } } diff --git a/StoneIsland/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/PushPlugin.java b/StoneIsland/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/PushPlugin.java index 32f72bf3..f6faaa2b 100644 --- a/StoneIsland/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/PushPlugin.java +++ b/StoneIsland/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/PushPlugin.java @@ -1,14 +1,13 @@ package com.adobe.phonegap.push; -import android.app.Activity; import android.app.NotificationManager; import android.content.Context; import android.content.SharedPreferences; import android.os.Bundle; import android.util.Log; -import com.google.firebase.iid.FirebaseInstanceId; -import com.google.firebase.messaging.FirebaseMessaging; +import com.google.android.gms.gcm.GcmPubSub; +import com.google.android.gms.iid.InstanceID; import org.apache.cordova.CallbackContext; import org.apache.cordova.CordovaInterface; @@ -30,7 +29,7 @@ import me.leolin.shortcutbadger.ShortcutBadger; public class PushPlugin extends CordovaPlugin implements PushConstants { - public static final String LOG_TAG = "Push_Plugin"; + public static final String LOG_TAG = "PushPlugin"; private static CallbackContext pushContext; private static CordovaWebView gWebView; @@ -60,7 +59,6 @@ public class PushPlugin extends CordovaPlugin implements PushConstants { Log.v(LOG_TAG, "execute: data=" + data.toString()); SharedPreferences sharedPref = getApplicationContext().getSharedPreferences(COM_ADOBE_PHONEGAP_PUSH, Context.MODE_PRIVATE); - String token = null; String senderID = null; try { @@ -68,19 +66,15 @@ public class PushPlugin extends CordovaPlugin implements PushConstants { Log.v(LOG_TAG, "execute: jo=" + jo.toString()); - senderID = getStringResourceByName(GCM_DEFAULT_SENDER_ID); + senderID = jo.getString(SENDER_ID); Log.v(LOG_TAG, "execute: senderID=" + senderID); - token = FirebaseInstanceId.getInstance().getToken(); + String savedSenderID = sharedPref.getString(SENDER_ID, ""); + registration_id = InstanceID.getInstance(getApplicationContext()).getToken(senderID, GCM); - if (token == null) { - token = FirebaseInstanceId.getInstance().getToken(senderID,FCM); - } - - if (!"".equals(token)) { - JSONObject json = new JSONObject().put(REGISTRATION_ID, token); - json.put(REGISTRATION_TYPE, FCM); + if (!"".equals(registration_id)) { + JSONObject json = new JSONObject().put(REGISTRATION_ID, registration_id); Log.v(LOG_TAG, "onRegistered: " + json.toString()); @@ -89,14 +83,14 @@ public class PushPlugin extends CordovaPlugin implements PushConstants { PushPlugin.sendEvent( json ); } else { - callbackContext.error("Empty registration ID received from FCM"); + callbackContext.error("Empty registration ID received from GCM"); return; } } catch (JSONException e) { Log.e(LOG_TAG, "execute: Got JSON Exception " + e.getMessage()); callbackContext.error(e.getMessage()); } catch (IOException e) { - Log.e(LOG_TAG, "execute: Got IO Exception " + e.getMessage()); + Log.e(LOG_TAG, "execute: Got JSON Exception " + e.getMessage()); callbackContext.error(e.getMessage()); } @@ -124,8 +118,6 @@ public class PushPlugin extends CordovaPlugin implements PushConstants { editor.putBoolean(CLEAR_NOTIFICATIONS, jo.optBoolean(CLEAR_NOTIFICATIONS, true)); editor.putBoolean(FORCE_SHOW, jo.optBoolean(FORCE_SHOW, false)); editor.putString(SENDER_ID, senderID); - editor.putString(MESSAGE_KEY, jo.optString(MESSAGE_KEY)); - editor.putString(TITLE_KEY, jo.optString(TITLE_KEY)); editor.commit(); } @@ -151,7 +143,7 @@ public class PushPlugin extends CordovaPlugin implements PushConstants { if (topics != null && !"".equals(registration_id)) { unsubscribeFromTopics(topics, registration_id); } else { - FirebaseInstanceId.getInstance().deleteInstanceId(); + InstanceID.getInstance(getApplicationContext()).deleteInstanceID(); Log.v(LOG_TAG, "UNREGISTER"); // Remove shared prefs @@ -202,13 +194,6 @@ public class PushPlugin extends CordovaPlugin implements PushConstants { callbackContext.success(); } }); - } else if (GET_APPLICATION_ICON_BADGE_NUMBER.equals(action)) { - cordova.getThreadPool().execute(new Runnable() { - public void run() { - Log.v(LOG_TAG, "getApplicationIconBadgeNumber"); - callbackContext.success(getApplicationIconBadgeNumber(getApplicationContext())); - } - }); } else if (CLEAR_ALL_NOTIFICATIONS.equals(action)) { cordova.getThreadPool().execute(new Runnable() { public void run() { @@ -227,6 +212,8 @@ public class PushPlugin extends CordovaPlugin implements PushConstants { callbackContext.success(); } catch (JSONException e) { callbackContext.error(e.getMessage()); + } catch (IOException e) { + callbackContext.error(e.getMessage()); } } }); @@ -240,6 +227,8 @@ public class PushPlugin extends CordovaPlugin implements PushConstants { callbackContext.success(); } catch (JSONException e) { callbackContext.error(e.getMessage()); + } catch (IOException e) { + callbackContext.error(e.getMessage()); } } }); @@ -270,41 +259,25 @@ public class PushPlugin extends CordovaPlugin implements PushConstants { /* * Sends the pushbundle extras to the client application. - * If the client application isn't currently active and the no-cache flag is not set, it is cached for later processing. + * If the client application isn't currently active, it is cached for later processing. */ public static void sendExtras(Bundle extras) { if (extras != null) { - String noCache = extras.getString(NO_CACHE); if (gWebView != null) { sendEvent(convertBundleToJson(extras)); - } else if(!"1".equals(noCache)){ + } else { Log.v(LOG_TAG, "sendExtras: caching extras to send at a later time."); gCachedExtras.add(extras); } } } - /* - * Retrives badge count from SharedPreferences - */ - public static int getApplicationIconBadgeNumber(Context context){ - SharedPreferences settings = context.getSharedPreferences(BADGE, Context.MODE_PRIVATE); - return settings.getInt(BADGE, 0); - } - - /* - * Sets badge count on application icon and in SharedPreferences - */ public static void setApplicationIconBadgeNumber(Context context, int badgeCount) { if (badgeCount > 0) { ShortcutBadger.applyCount(context, badgeCount); - }else{ + } else { ShortcutBadger.removeCount(context); } - - SharedPreferences.Editor editor = context.getSharedPreferences(BADGE, Context.MODE_PRIVATE).edit(); - editor.putInt(BADGE, Math.max(badgeCount, 0)); - editor.apply(); } @Override @@ -342,7 +315,23 @@ public class PushPlugin extends CordovaPlugin implements PushConstants { notificationManager.cancelAll(); } - private void subscribeToTopics(JSONArray topics, String registrationToken) { + /** + * Transform `topic name` to `topic path` + * Normally, the `topic` inputed from end-user is `topic name` only. + * We should convert them to GCM `topic path` + * Example: + * when topic name = 'my-topic' + * then topic path = '/topics/my-topic' + * + * @param String topic The topic name + * @return The topic path + */ + private String getTopicPath(String topic) + { + return "/topics/" + topic; + } + + private void subscribeToTopics(JSONArray topics, String registrationToken) throws IOException { if (topics != null) { String topic = null; for (int i=0; i<topics.length(); i++) { @@ -352,10 +341,16 @@ public class PushPlugin extends CordovaPlugin implements PushConstants { } } - private void subscribeToTopic(String topic, String registrationToken) { - if (topic != null) { - Log.d(LOG_TAG, "Subscribing to topic: " + topic); - FirebaseMessaging.getInstance().subscribeToTopic(topic); + private void subscribeToTopic(String topic, String registrationToken) throws IOException + { + try { + if (topic != null) { + Log.d(LOG_TAG, "Subscribing to topic: " + topic); + GcmPubSub.getInstance(getApplicationContext()).subscribe(registrationToken, getTopicPath(topic), null); + } + } catch (IOException e) { + Log.e(LOG_TAG, "Failed to subscribe to topic: " + topic, e); + throw e; } } @@ -363,20 +358,29 @@ public class PushPlugin extends CordovaPlugin implements PushConstants { if (topics != null) { String topic = null; for (int i=0; i<topics.length(); i++) { - topic = topics.optString(i, null); - unsubscribeFromTopic(topic, registrationToken); - if (topic != null) { - Log.d(LOG_TAG, "Unsubscribing to topic: " + topic); - FirebaseMessaging.getInstance().unsubscribeFromTopic(topic); + try { + topic = topics.optString(i, null); + if (topic != null) { + Log.d(LOG_TAG, "Unsubscribing to topic: " + topic); + GcmPubSub.getInstance(getApplicationContext()).unsubscribe(registrationToken, getTopicPath(topic)); + } + } catch (IOException e) { + Log.e(LOG_TAG, "Failed to unsubscribe to topic: " + topic, e); } } } } - private void unsubscribeFromTopic(String topic, String registrationToken) { - if (topic != null) { - Log.d(LOG_TAG, "Unsubscribing to topic: " + topic); - FirebaseMessaging.getInstance().unsubscribeFromTopic(topic); + private void unsubscribeFromTopic(String topic, String registrationToken) throws IOException + { + try { + if (topic != null) { + Log.d(LOG_TAG, "Unsubscribing to topic: " + topic); + GcmPubSub.getInstance(getApplicationContext()).unsubscribe(registrationToken, getTopicPath(topic)); + } + } catch (IOException e) { + Log.e(LOG_TAG, "Failed to unsubscribe to topic: " + topic, e); + throw e; } } @@ -409,9 +413,6 @@ public class PushPlugin extends CordovaPlugin implements PushConstants { else if (key.equals(FOREGROUND)) { additionalData.put(key, extras.getBoolean(FOREGROUND)); } - else if (key.equals(DISMISSED)) { - additionalData.put(key, extras.getBoolean(DISMISSED)); - } else if ( value instanceof String ) { String strValue = (String)value; try { @@ -443,13 +444,6 @@ public class PushPlugin extends CordovaPlugin implements PushConstants { return null; } - private String getStringResourceByName(String aString) { - Activity activity = cordova.getActivity(); - String packageName = activity.getPackageName(); - int resId = activity.getResources().getIdentifier(aString, "string", packageName); - return activity.getString(resId); - } - public static boolean isInForeground() { return gForeground; } diff --git a/StoneIsland/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/RegistrationIntentService.java b/StoneIsland/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/RegistrationIntentService.java new file mode 100644 index 00000000..b181e88e --- /dev/null +++ b/StoneIsland/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/RegistrationIntentService.java @@ -0,0 +1,38 @@ +package com.adobe.phonegap.push; + +import android.content.Context; + +import android.app.IntentService; +import android.content.Intent; +import android.content.SharedPreferences; +import android.util.Log; + +import com.google.android.gms.gcm.GoogleCloudMessaging; +import com.google.android.gms.iid.InstanceID; + +import java.io.IOException; + +public class RegistrationIntentService extends IntentService implements PushConstants { + public static final String LOG_TAG = "PushPlugin_RegistrationIntentService"; + + public RegistrationIntentService() { + super(LOG_TAG); + } + + @Override + protected void onHandleIntent(Intent intent) { + SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences(COM_ADOBE_PHONEGAP_PUSH, Context.MODE_PRIVATE); + + try { + InstanceID instanceID = InstanceID.getInstance(this); + String senderID = sharedPreferences.getString(SENDER_ID, ""); + String token = instanceID.getToken(senderID, + GoogleCloudMessaging.INSTANCE_ID_SCOPE, null); + PushPlugin.setRegistrationID(token); + Log.i(LOG_TAG, "new GCM Registration Token: " + token); + + } catch (Exception e) { + Log.d(LOG_TAG, "Failed to complete token refresh", e); + } + } +} diff --git a/StoneIsland/plugins/phonegap-plugin-push/src/browser/manifest.json b/StoneIsland/plugins/phonegap-plugin-push/src/browser/manifest.json index eff52c74..ce8390ab 100644 --- a/StoneIsland/plugins/phonegap-plugin-push/src/browser/manifest.json +++ b/StoneIsland/plugins/phonegap-plugin-push/src/browser/manifest.json @@ -1,4 +1,4 @@ { "name": "Push Demo", - "gcm_sender_id": "996231231186" + "gcm_sender_id": "85075801930" } diff --git a/StoneIsland/plugins/phonegap-plugin-push/src/ios/PushPlugin.h b/StoneIsland/plugins/phonegap-plugin-push/src/ios/PushPlugin.h index 4cc1dcb0..276a0080 100644 --- a/StoneIsland/plugins/phonegap-plugin-push/src/ios/PushPlugin.h +++ b/StoneIsland/plugins/phonegap-plugin-push/src/ios/PushPlugin.h @@ -29,7 +29,7 @@ @protocol GGLInstanceIDDelegate; @protocol GCMReceiverDelegate; -@interface PushPlugin : CDVPlugin +@interface PushPlugin : CDVPlugin<GGLInstanceIDDelegate, GCMReceiverDelegate> { NSDictionary *notificationMessage; BOOL isInline; @@ -68,12 +68,13 @@ - (void)didSendDataMessageWithID:(NSString *)messageID; - (void)didDeleteMessagesOnServer; -// FCM Features -@property(nonatomic, assign) BOOL usesFCM; -@property(nonatomic, strong) NSNumber *fcmSandbox; -@property(nonatomic, strong) NSString *fcmSenderId; -@property(nonatomic, strong) NSDictionary *fcmRegistrationOptions; -@property(nonatomic, strong) NSString *fcmRegistrationToken; -@property(nonatomic, strong) NSArray *fcmTopics; +// GCM Features +@property(nonatomic, assign) BOOL usesGCM; +@property(nonatomic, strong) NSNumber* gcmSandbox; +@property(nonatomic, strong) NSString *gcmSenderId; +@property(nonatomic, strong) NSDictionary *gcmRegistrationOptions; +@property(nonatomic, strong) void (^gcmRegistrationHandler) (NSString *registrationToken, NSError *error); +@property(nonatomic, strong) NSString *gcmRegistrationToken; +@property(nonatomic, strong) NSArray *gcmTopics; @end diff --git a/StoneIsland/plugins/phonegap-plugin-push/src/ios/PushPlugin.m b/StoneIsland/plugins/phonegap-plugin-push/src/ios/PushPlugin.m index 90475d10..a176b9af 100644 --- a/StoneIsland/plugins/phonegap-plugin-push/src/ios/PushPlugin.m +++ b/StoneIsland/plugins/phonegap-plugin-push/src/ios/PushPlugin.m @@ -27,9 +27,8 @@ #define GMP_NO_MODULES true #import "PushPlugin.h" -@import FirebaseInstanceID; -@import FirebaseMessaging; -@import FirebaseAnalytics; +#import "GoogleCloudMessaging.h" +#import "GGLInstanceIDHeaders.h" @implementation PushPlugin : CDVPlugin @@ -43,62 +42,78 @@ @synthesize clearBadge; @synthesize handlerObj; -@synthesize usesFCM; -@synthesize fcmSandbox; -@synthesize fcmSenderId; -@synthesize fcmRegistrationOptions; -@synthesize fcmRegistrationToken; -@synthesize fcmTopics; +@synthesize usesGCM; +@synthesize gcmSandbox; +@synthesize gcmSenderId; +@synthesize gcmRegistrationOptions; +@synthesize gcmRegistrationHandler; +@synthesize gcmRegistrationToken; +@synthesize gcmTopics; --(void)initRegistration; +-(void)initGCMRegistrationHandler; { - NSString * registrationToken = [[FIRInstanceID instanceID] token]; + __weak __block PushPlugin *weakSelf = self; + gcmRegistrationHandler = ^(NSString *registrationToken, NSError *error){ + if (registrationToken != nil) { + NSLog(@"GCM Registration Token: %@", registrationToken); + [weakSelf setGcmRegistrationToken: registrationToken]; - if (registrationToken != nil) { - NSLog(@"FCM Registration Token: %@", registrationToken); - [self setFcmRegistrationToken: registrationToken]; - - id topics = [self fcmTopics]; - if (topics != nil) { - for (NSString *topic in topics) { - NSLog(@"subscribe to topic: %@", topic); - id pubSub = [FIRMessaging messaging]; - [pubSub subscribeToTopic:topic]; + id topics = [weakSelf gcmTopics]; + if (topics != nil) { + for (NSString *topic in topics) { + NSLog(@"subscribe from topic: %@", topic); + id pubSub = [GCMPubSub sharedInstance]; + [pubSub subscribeWithToken: [weakSelf gcmRegistrationToken] + topic:[NSString stringWithFormat:@"/topics/%@", topic] + options:nil + handler:^void(NSError *error) { + if (error) { + if (error.code == 3001) { + NSLog(@"Already subscribed to %@", topic); + } else { + NSLog(@"Failed to subscribe to topic %@: %@", topic, error); + } + } + else { + NSLog(@"Successfully subscribe to topic %@", topic); + } + }]; + } } - } - - [self registerWithToken:registrationToken]; - } else { - NSLog(@"FCM token is null"); - } + [weakSelf registerWithToken:registrationToken]; + } else { + NSLog(@"Registration to GCM failed with error: %@", error.localizedDescription); + [weakSelf failWithMessage:self.callbackId withMsg:@"" withError:error]; + } + }; } -// FCM refresh token +// GCM refresh token // Unclear how this is testable under normal circumstances - (void)onTokenRefresh { #if !TARGET_IPHONE_SIMULATOR // A rotation of the registration tokens is happening, so the app needs to request a new token. - NSLog(@"The FCM registration token needs to be changed."); - [[FIRInstanceID instanceID] token]; - [self initRegistration]; + NSLog(@"The GCM registration token needs to be changed."); + [[GGLInstanceID sharedInstance] tokenWithAuthorizedEntity:[self gcmSenderId] + scope:kGGLInstanceIDScopeGCM + options:[self gcmRegistrationOptions] + handler:[self gcmRegistrationHandler]]; #endif } -// contains error info -- (void)sendDataMessageFailure:(NSNotification *)notification { - NSLog(@"sendDataMessageFailure"); -} -- (void)sendDataMessageSuccess:(NSNotification *)notification { - NSLog(@"sendDataMessageSuccess"); -} - -- (void)didSendDataMessageWithID:messageID { - NSLog(@"didSendDataMessageWithID"); +- (void)willSendDataMessageWithID:(NSString *)messageID error:(NSError *)error { + NSLog(@"willSendDataMessageWithID"); + if (error) { + // Failed to send the message. + } else { + // Will send message, you can save the messageID to track the message + } } -- (void)willSendDataMessageWithID:messageID error:error { +- (void)didSendDataMessageWithID:(NSString *)messageID { NSLog(@"willSendDataMessageWithID"); + // Did successfully send message identified by messageID } - (void)didDeleteMessagesOnServer { @@ -113,10 +128,20 @@ NSArray* topics = [command argumentAtIndex:0]; if (topics != nil) { - id pubSub = [FIRMessaging messaging]; + id pubSub = [GCMPubSub sharedInstance]; for (NSString *topic in topics) { NSLog(@"unsubscribe from topic: %@", topic); - [pubSub unsubscribeFromTopic:topic]; + [pubSub unsubscribeWithToken: [self gcmRegistrationToken] + topic:[NSString stringWithFormat:@"/topics/%@", topic] + options:nil + handler:^void(NSError *error) { + if (error) { + NSLog(@"Failed to unsubscribe from topic %@: %@", topic, error); + } + else { + NSLog(@"Successfully unsubscribe from topic %@", topic); + } + }]; } } else { [[UIApplication sharedApplication] unregisterForRemoteNotifications]; @@ -130,10 +155,25 @@ if (topic != nil) { NSLog(@"subscribe from topic: %@", topic); - id pubSub = [FIRMessaging messaging]; - [pubSub subscribeToTopic:topic]; - NSLog(@"Successfully subscribe to topic %@", topic); - [self successWithMessage:command.callbackId withMsg:[NSString stringWithFormat:@"Successfully subscribe to topic %@", topic]]; + id pubSub = [GCMPubSub sharedInstance]; + [pubSub subscribeWithToken: [self gcmRegistrationToken] + topic:[NSString stringWithFormat:@"/topics/%@", topic] + options:nil + handler:^void(NSError *error) { + if (error) { + if (error.code == 3001) { + NSLog(@"Already subscribed to %@", topic); + [self successWithMessage:command.callbackId withMsg:[NSString stringWithFormat:@"Already subscribed to %@", topic]]; + } else { + NSLog(@"Failed to subscribe to topic %@: %@", topic, error); + [self failWithMessage:command.callbackId withMsg:[NSString stringWithFormat:@"Failed to subscribe to topic %@", topic] withError:error]; + } + } + else { + NSLog(@"Successfully subscribe to topic %@", topic); + [self successWithMessage:command.callbackId withMsg:[NSString stringWithFormat:@"Successfully subscribe to topic %@", topic]]; + } + }]; } else { NSLog(@"There is no topic to subscribe"); [self successWithMessage:command.callbackId withMsg:@"There is no topic to subscribe"]; @@ -146,10 +186,19 @@ if (topic != nil) { NSLog(@"unsubscribe from topic: %@", topic); - id pubSub = [FIRMessaging messaging]; - [pubSub unsubscribeFromTopic:topic]; - NSLog(@"Successfully unsubscribe from topic %@", topic); - [self successWithMessage:command.callbackId withMsg:[NSString stringWithFormat:@"Successfully unsubscribe from topic %@", topic]]; + id pubSub = [GCMPubSub sharedInstance]; + [pubSub unsubscribeWithToken: [self gcmRegistrationToken] + topic:[NSString stringWithFormat:@"/topics/%@", topic] + options:nil + handler:^void(NSError *error) { + if (error) { + NSLog(@"Failed to unsubscribe to topic %@: %@", topic, error); + [self failWithMessage:command.callbackId withMsg:[NSString stringWithFormat:@"Failed to unsubscribe to topic %@", topic] withError:error]; + } else { + NSLog(@"Successfully unsubscribe to topic %@", topic); + [self successWithMessage:command.callbackId withMsg:[NSString stringWithFormat:@"Successfully unsubscribe to topic %@", topic]]; + } + }]; } else { NSLog(@"There is no topic to unsubscribe"); [self successWithMessage:command.callbackId withMsg:@"There is no topic to unsubscribe"]; @@ -158,22 +207,6 @@ - (void)init:(CDVInvokedUrlCommand*)command; { - [[NSNotificationCenter defaultCenter] - addObserver:self selector:@selector(onTokenRefresh) - name:kFIRInstanceIDTokenRefreshNotification object:nil]; - - [[NSNotificationCenter defaultCenter] - addObserver:self selector:@selector(sendDataMessageFailure:) - name:FIRMessagingSendErrorNotification object:nil]; - - [[NSNotificationCenter defaultCenter] - addObserver:self selector:@selector(sendDataMessageSuccess:) - name:FIRMessagingSendSuccessNotification object:nil]; - - [[NSNotificationCenter defaultCenter] - addObserver:self selector:@selector(didDeleteMessagesOnServer) - name:FIRMessagingMessagesDeletedNotification object:nil]; - [self.commandDelegate runInBackground:^ { NSLog(@"Push Plugin register called"); @@ -182,10 +215,13 @@ NSMutableDictionary* options = [command.arguments objectAtIndex:0]; NSMutableDictionary* iosOptions = [options objectForKey:@"ios"]; - NSArray* topics = [iosOptions objectForKey:@"topics"]; - [self setFcmTopics:topics]; + NSArray* topics = [iosOptions objectForKey:@"topics"]; + [self setGcmTopics:topics]; +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 UIUserNotificationType UserNotificationTypes = UIUserNotificationTypeNone; +#endif + UIRemoteNotificationType notificationTypes = UIRemoteNotificationTypeNone; id badgeArg = [iosOptions objectForKey:@"badge"]; id soundArg = [iosOptions objectForKey:@"sound"]; @@ -194,20 +230,32 @@ if (([badgeArg isKindOfClass:[NSString class]] && [badgeArg isEqualToString:@"true"]) || [badgeArg boolValue]) { + notificationTypes |= UIRemoteNotificationTypeBadge; +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 UserNotificationTypes |= UIUserNotificationTypeBadge; +#endif } if (([soundArg isKindOfClass:[NSString class]] && [soundArg isEqualToString:@"true"]) || [soundArg boolValue]) { + notificationTypes |= UIRemoteNotificationTypeSound; +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 UserNotificationTypes |= UIUserNotificationTypeSound; +#endif } if (([alertArg isKindOfClass:[NSString class]] && [alertArg isEqualToString:@"true"]) || [alertArg boolValue]) { + notificationTypes |= UIRemoteNotificationTypeAlert; +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 UserNotificationTypes |= UIUserNotificationTypeAlert; +#endif } + notificationTypes |= UIRemoteNotificationTypeNewsstandContentAvailability; +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 UserNotificationTypes |= UIUserNotificationActivationModeBackground; +#endif if (clearBadgeArg == nil || ([clearBadgeArg isKindOfClass:[NSString class]] && [clearBadgeArg isEqualToString:@"false"]) || ![clearBadgeArg boolValue]) { NSLog(@"PushPlugin.register: setting badge to false"); @@ -219,8 +267,12 @@ } NSLog(@"PushPlugin.register: clear badge is set to %d", clearBadge); + if (notificationTypes == UIRemoteNotificationTypeNone) + NSLog(@"PushPlugin.register: Push notification type is set to none"); + isInline = NO; +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 NSLog(@"PushPlugin.register: better button setup"); // setup action buttons NSMutableSet *categories = [[NSMutableSet alloc] init]; @@ -277,46 +329,45 @@ } } +#else + NSLog(@"PushPlugin.register: action buttons only supported on iOS8 and above"); +#endif + +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 if ([[UIApplication sharedApplication]respondsToSelector:@selector(registerUserNotificationSettings:)]) { UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UserNotificationTypes categories:categories]; [[UIApplication sharedApplication] registerUserNotificationSettings:settings]; [[UIApplication sharedApplication] registerForRemoteNotifications]; + } else { + [[UIApplication sharedApplication] registerForRemoteNotificationTypes: + (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)]; } - - // Read GoogleService-Info.plist - NSString *path = [[NSBundle mainBundle] pathForResource:@"GoogleService-Info" ofType:@"plist"]; - - // Load the file content and read the data into arrays - NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path]; - fcmSenderId = [dict objectForKey:@"GCM_SENDER_ID"]; - BOOL isGcmEnabled = [[dict valueForKey:@"IS_GCM_ENABLED"] boolValue]; - - NSLog(@"FCM Sender ID %@", fcmSenderId); +#else + [[UIApplication sharedApplication] registerForRemoteNotificationTypes: + (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)]; +#endif // GCM options - [self setFcmSenderId: fcmSenderId]; - if(isGcmEnabled && [[self fcmSenderId] length] > 0) { - NSLog(@"Using FCM Notification"); - [self setUsesFCM: YES]; - dispatch_async(dispatch_get_main_queue(), ^{ - if([FIRApp defaultApp] == nil) - [FIRApp configure]; - [self initRegistration]; - }); + [self setGcmSenderId: [iosOptions objectForKey:@"senderID"]]; + NSLog(@"GCM Sender ID %@", gcmSenderId); + if([[self gcmSenderId] length] > 0) { + NSLog(@"Using GCM Notification"); + [self setUsesGCM: YES]; + [self initGCMRegistrationHandler]; } else { NSLog(@"Using APNS Notification"); - [self setUsesFCM:NO]; + [self setUsesGCM:NO]; } - id fcmSandboxArg = [iosOptions objectForKey:@"fcmSandbox"]; + id gcmSandBoxArg = [iosOptions objectForKey:@"gcmSandbox"]; - [self setFcmSandbox:@NO]; - if ([self usesFCM] && - (([fcmSandboxArg isKindOfClass:[NSString class]] && [fcmSandboxArg isEqualToString:@"true"]) || - [fcmSandboxArg boolValue])) + [self setGcmSandbox:@NO]; + if ([self usesGCM] && + (([gcmSandBoxArg isKindOfClass:[NSString class]] && [gcmSandBoxArg isEqualToString:@"true"]) || + [gcmSandBoxArg boolValue])) { - NSLog(@"Using FCM Sandbox"); - [self setFcmSandbox:@YES]; + NSLog(@"Using GCM Sandbox"); + [self setGcmSandbox:@YES]; } if (notificationMessage) { // if there is a pending startup notification @@ -371,8 +422,14 @@ [results setValue:[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"] forKey:@"appVersion"]; // Check what Notifications the user has turned on. We registered for all three, but they may have manually disabled some or all of them. +#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending) - NSUInteger rntypes = [[[UIApplication sharedApplication] currentUserNotificationSettings] types]; + NSUInteger rntypes; + if (!SYSTEM_VERSION_LESS_THAN(@"8.0")) { + rntypes = [[[UIApplication sharedApplication] currentUserNotificationSettings] types]; + } else { + rntypes = [[UIApplication sharedApplication] enabledRemoteNotificationTypes]; + } // Set the defaults to disabled unless we find otherwise... NSString *pushBadge = @"disabled"; @@ -383,13 +440,13 @@ // one is actually disabled. So we are literally checking to see if rnTypes matches what is turned on, instead of by number. The "tricky" part is that the // single notification types will only match if they are the ONLY one enabled. Likewise, when we are checking for a pair of notifications, it will only be // true if those two notifications are on. This is why the code is written this way - if(rntypes & UIUserNotificationTypeBadge){ + if(rntypes & UIRemoteNotificationTypeBadge){ pushBadge = @"enabled"; } - if(rntypes & UIUserNotificationTypeAlert) { + if(rntypes & UIRemoteNotificationTypeAlert) { pushAlert = @"enabled"; } - if(rntypes & UIUserNotificationTypeSound) { + if(rntypes & UIRemoteNotificationTypeSound) { pushSound = @"enabled"; } @@ -403,7 +460,24 @@ [results setValue:dev.model forKey:@"deviceModel"]; [results setValue:dev.systemVersion forKey:@"deviceSystemVersion"]; - if(![self usesFCM]) { + if([self usesGCM]) { + GGLInstanceIDConfig *instanceIDConfig = [GGLInstanceIDConfig defaultConfig]; + instanceIDConfig.delegate = self; + [[GGLInstanceID sharedInstance] startWithConfig:instanceIDConfig]; + + [self setGcmRegistrationOptions: @{kGGLInstanceIDRegisterAPNSOption:deviceToken, + kGGLInstanceIDAPNSServerTypeSandboxOption:[self gcmSandbox]}]; + + [[GGLInstanceID sharedInstance] tokenWithAuthorizedEntity:[self gcmSenderId] + scope:kGGLInstanceIDScopeGCM + options:[self gcmRegistrationOptions] + handler:[self gcmRegistrationHandler]]; + + GCMConfig *gcmConfig = [GCMConfig defaultConfig]; + gcmConfig.receiverDelegate = self; + [[GCMService sharedInstance] startWithConfig:gcmConfig]; + + } else { [self registerWithToken: token]; } #endif @@ -536,36 +610,31 @@ [self.commandDelegate sendPluginResult:commandResult callbackId:command.callbackId]; } --(void)successWithMessage:(NSString *)myCallbackId withMsg:(NSString *)message +-(void)successWithMessage:(NSString *)callbackId withMsg:(NSString *)message { - if (myCallbackId != nil) + if (callbackId != nil) { CDVPluginResult *commandResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:message]; - [self.commandDelegate sendPluginResult:commandResult callbackId:myCallbackId]; + [self.commandDelegate sendPluginResult:commandResult callbackId:callbackId]; } } -(void)registerWithToken:(NSString*)token; { // Send result to trigger 'registration' event but keep callback - NSMutableDictionary* message = [NSMutableDictionary dictionaryWithCapacity:2]; + NSMutableDictionary* message = [NSMutableDictionary dictionaryWithCapacity:1]; [message setObject:token forKey:@"registrationId"]; - if ([self usesFCM]) { - [message setObject:@"FCM" forKey:@"registrationType"]; - } else { - [message setObject:@"APNS" forKey:@"registrationType"]; - } CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:message]; [pluginResult setKeepCallbackAsBool:YES]; [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId]; } --(void)failWithMessage:(NSString *)myCallbackId withMsg:(NSString *)message withError:(NSError *)error +-(void)failWithMessage:(NSString *)callbackId withMsg:(NSString *)message withError:(NSError *)error { NSString *errorMessage = (error) ? [NSString stringWithFormat:@"%@ - %@", message, [error localizedDescription]] : message; CDVPluginResult *commandResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:errorMessage]; - [self.commandDelegate sendPluginResult:commandResult callbackId:myCallbackId]; + [self.commandDelegate sendPluginResult:commandResult callbackId:callbackId]; } -(void) finish:(CDVInvokedUrlCommand*)command diff --git a/StoneIsland/plugins/phonegap-plugin-push/src/js/push.js b/StoneIsland/plugins/phonegap-plugin-push/src/js/push.js deleted file mode 100644 index 150af344..00000000 --- a/StoneIsland/plugins/phonegap-plugin-push/src/js/push.js +++ /dev/null @@ -1,316 +0,0 @@ -/* global cordova:false */ -/* globals window */ - -/*! - * Module dependencies. - */ - -const exec = cordova.require('cordova/exec'); - -class PushNotification { - /** - * PushNotification constructor. - * - * @param {Object} options to initiate Push Notifications. - * @return {PushNotification} instance that can be monitored and cancelled. - */ - constructor(options) { - this.handlers = { - registration: [], - notification: [], - error: [], - }; - - // require options parameter - if (typeof options === 'undefined') { - throw new Error('The options argument is required.'); - } - - // store the options to this object instance - this.options = options; - - // triggered on registration and notification - const success = (result) => { - if (result && typeof result.registrationId !== 'undefined') { - this.emit('registration', result); - } else if (result && result.additionalData && - typeof result.additionalData.actionCallback !== 'undefined') { - const executeFuctionOrEmitEventByName = (functionName, context, ...args) => { - const namespaces = functionName.split('.'); - const func = namespaces.pop(); - for (let i = 0; i < namespaces.length; i++) { - context = context[namespaces[i]]; - } - - if (typeof context[func] === 'function') { - context[func].call(context, args); - } else { - this.emit(functionName, args); - } - }; - - executeFuctionOrEmitEventByName(result.additionalData.actionCallback, window, result); - } else if (result) { - this.emit('notification', result); - } - }; - - // triggered on error - const fail = (msg) => { - const e = (typeof msg === 'string') ? new Error(msg) : msg; - this.emit('error', e); - }; - - // wait at least one process tick to allow event subscriptions - setTimeout(() => { - exec(success, fail, 'PushNotification', 'init', [options]); - }, 10); - } - - /** - * Unregister from push notifications - */ - unregister(successCallback, errorCallback = () => {}, options) { - if (typeof errorCallback !== 'function') { - console.log('PushNotification.unregister failure: failure parameter not a function'); - return; - } - - if (typeof successCallback !== 'function') { - console.log('PushNotification.unregister failure: success callback parameter ' + - ' must be a function'); - return; - } - - const cleanHandlersAndPassThrough = () => { - if (!options) { - this.handlers = { - registration: [], - notification: [], - error: [], - }; - } - successCallback(); - }; - - exec(cleanHandlersAndPassThrough, errorCallback, 'PushNotification', 'unregister', [options]); - } - - /** - * subscribe to a topic - * @param {String} topic topic to subscribe - * @param {Function} successCallback success callback - * @param {Function} errorCallback error callback - * @return {void} - */ - subscribe(topic, successCallback, errorCallback = () => {}) { - if (typeof errorCallback !== 'function') { - console.log('PushNotification.subscribe failure: ' + - 'failure parameter not a function'); - return; - } - - if (typeof successCallback !== 'function') { - console.log('PushNotification.subscribe failure: ' + - 'success callback parameter must be a function'); - return; - } - - exec(successCallback, errorCallback, 'PushNotification', 'subscribe', [topic]); - } - - /** - * unsubscribe to a topic - * @param {String} topic topic to unsubscribe - * @param {Function} successCallback success callback - * @param {Function} errorCallback error callback - * @return {void} - */ - unsubscribe(topic, successCallback, errorCallback = () => {}) { - if (typeof errorCallback !== 'function') { - console.log('PushNotification.unsubscribe failure: failure parameter not a function'); - return; - } - - if (typeof successCallback !== 'function') { - console.log('PushNotification.unsubscribe failure: ' + - 'success callback parameter must be a function'); - return; - } - - exec(successCallback, errorCallback, 'PushNotification', 'unsubscribe', [topic]); - } - - - /** - * Call this to set the application icon badge - */ - setApplicationIconBadgeNumber(successCallback, errorCallback = () => {}, badge) { - if (typeof errorCallback !== 'function') { - console.log('PushNotification.setApplicationIconBadgeNumber failure: failure ' + - 'parameter not a function'); - return; - } - - if (typeof successCallback !== 'function') { - console.log('PushNotification.setApplicationIconBadgeNumber failure: success ' + - 'callback parameter must be a function'); - return; - } - - exec(successCallback, errorCallback, 'PushNotification', - 'setApplicationIconBadgeNumber', [{ badge }]); - } - - /** - * Get the application icon badge - */ - - getApplicationIconBadgeNumber(successCallback, errorCallback = () => {}) { - if (typeof errorCallback !== 'function') { - console.log('PushNotification.getApplicationIconBadgeNumber failure: failure ' + - 'parameter not a function'); - return; - } - - if (typeof successCallback !== 'function') { - console.log('PushNotification.getApplicationIconBadgeNumber failure: success ' + - 'callback parameter must be a function'); - return; - } - - exec(successCallback, errorCallback, 'PushNotification', 'getApplicationIconBadgeNumber', []); - } - - /** - * Clear all notifications - */ - - clearAllNotifications(successCallback = () => {}, errorCallback = () => {}) { - if (typeof errorCallback !== 'function') { - console.log('PushNotification.clearAllNotifications failure: failure parameter ' + - 'not a function'); - return; - } - - if (typeof successCallback !== 'function') { - console.log('PushNotification.clearAllNotifications failure: success callback ' + - 'parameter must be a function'); - return; - } - - exec(successCallback, errorCallback, 'PushNotification', 'clearAllNotifications', []); - } - /** - * Listen for an event. - * - * The following events are supported: - * - * - registration - * - notification - * - error - * - * @param {String} eventName to subscribe to. - * @param {Function} callback triggered on the event. - */ - - on(eventName, callback) { - if (!this.handlers.hasOwnProperty(eventName)) { - this.handlers[eventName] = []; - } - this.handlers[eventName].push(callback); - } - - /** - * Remove event listener. - * - * @param {String} eventName to match subscription. - * @param {Function} handle function associated with event. - */ - - off(eventName, handle) { - if (this.handlers.hasOwnProperty(eventName)) { - const handleIndex = this.handlers[eventName].indexOf(handle); - if (handleIndex >= 0) { - this.handlers[eventName].splice(handleIndex, 1); - } - } - } - - /** - * Emit an event. - * - * This is intended for internal use only. - * - * @param {String} eventName is the event to trigger. - * @param {*} all arguments are passed to the event listeners. - * - * @return {Boolean} is true when the event is triggered otherwise false. - */ - - emit(...args) { - const eventName = args.shift(); - - if (!this.handlers.hasOwnProperty(eventName)) { - return false; - } - - for (let i = 0, length = this.handlers[eventName].length; i < length; i++) { - const callback = this.handlers[eventName][i]; - if (typeof callback === 'function') { - callback.apply(undefined, args); - } else { - console.log(`event handler: ${eventName} must be a function`); - } - } - - return true; - } - - finish(successCallback = () => {}, errorCallback = () => {}, id = 'handler') { - if (typeof successCallback !== 'function') { - console.log('finish failure: success callback parameter must be a function'); - return; - } - - if (typeof errorCallback !== 'function') { - console.log('finish failure: failure parameter not a function'); - return; - } - - exec(successCallback, errorCallback, 'PushNotification', 'finish', [id]); - } -} - -/*! - * Push Notification Plugin. - */ - -module.exports = { - /** - * Register for Push Notifications. - * - * This method will instantiate a new copy of the PushNotification object - * and start the registration process. - * - * @param {Object} options - * @return {PushNotification} instance - */ - - init: (options) => { - return new PushNotification(options); - }, - - hasPermission: (successCallback, errorCallback) => { - exec(successCallback, errorCallback, 'PushNotification', 'hasPermission', []); - }, - - /** - * PushNotification Object. - * - * Expose the PushNotification object for direct use - * and testing. Typically, you should use the - * .init helper method. - */ - PushNotification, -}; diff --git a/StoneIsland/plugins/phonegap-plugin-push/src/windows/PushPluginProxy.js b/StoneIsland/plugins/phonegap-plugin-push/src/windows/PushPluginProxy.js index eb552dc0..ac04f39d 100644 --- a/StoneIsland/plugins/phonegap-plugin-push/src/windows/PushPluginProxy.js +++ b/StoneIsland/plugins/phonegap-plugin-push/src/windows/PushPluginProxy.js @@ -88,12 +88,6 @@ module.exports = { } catch(ex) { onFail(ex); } - }, - subscribe: function() { - console.log("Subscribe is unsupported"); - }, - unsubscribe: function() { - console.log("Subscribe is unsupported"); } }; require("cordova/exec/proxy").add("PushNotification", module.exports); |
