package com.buddycloud.notifications; import org.json.JSONException; import org.json.JSONObject; import android.app.IntentService; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager.NameNotFoundException; import android.os.Bundle; import android.preference.PreferenceManager; import com.buddycloud.init.ApplicationManager; import com.buddycloud.log.Logger; import com.buddycloud.model.ModelCallback; import com.buddycloud.model.ModelCallbackImpl; import com.buddycloud.model.NotificationSettingsModel; import com.buddycloud.model.SyncModel; import com.buddycloud.preferences.Preferences; import com.buddycloud.utils.VersionUtils; import com.google.android.gms.gcm.GoogleCloudMessaging; public class GCMIntentService extends IntentService { public static final String GCM_NOTIFICATION_EVENT = "com.buddycloud.GCM_NOTIFICATION_EVENT"; private static final String TAG = GCMIntentService.class.getName(); public GCMIntentService() { super("GCMIntentService"); } @Override protected void onHandleIntent(Intent remoteIntent) { Logger.info(TAG, "GCM reveived " + remoteIntent.toString()); GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this); String messageType = gcm.getMessageType(remoteIntent); Bundle extras = remoteIntent.getExtras(); if (!extras.isEmpty()) { if (GoogleCloudMessaging. MESSAGE_TYPE_SEND_ERROR.equals(messageType)) { Logger.info(TAG, "Send error: " + extras.toString()); } else if (GoogleCloudMessaging. MESSAGE_TYPE_DELETED.equals(messageType)) { Logger.info(TAG, "Deleted messages on server: " + extras.toString()); } else if (GoogleCloudMessaging. MESSAGE_TYPE_MESSAGE.equals(messageType)) { // If it's a regular GCM message, do some work. final Context context = ApplicationManager.getAppContext(); final SyncModel syncModel = SyncModel.getInstance(); SyncModel.getInstance().syncNoSummary(context, new ModelCallbackImpl<Void>(){ @Override public void success(Void response) { syncModel.fill(context, new ModelCallbackImpl<Void>()); } @Override public void error(Throwable throwable) { success(null); } }); GCMEvent event = GCMEvent.valueOf(remoteIntent.getStringExtra("event")); GCMNotificationListener notificationListener = createNotificationListener(context, event); if (notificationListener != null) { notificationListener.onMessage(event, context, remoteIntent); } } } // Release the wake lock provided by the WakefulBroadcastReceiver. GCMBroadcastReceiver.completeWakefulIntent(remoteIntent); } private GCMNotificationListener createNotificationListener( Context context, GCMEvent event) { SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context); switch (event) { case POST_AFTER_MY_POST: if (!getPref(sharedPrefs, NotificationSettingsModel.PREF_COMMENTS_NOTIFICATION)) { return null; } case POST_ON_SUBSCRIBED_CHANNEL: if (!getPref(sharedPrefs, NotificationSettingsModel.PREF_ANYCHANNEL_NOTIFICATION)) { return null; } case POST_ON_MY_CHANNEL: if (!getPref(sharedPrefs, NotificationSettingsModel.PREF_MYCHANNEL_NOTIFICATION)) { return null; } case MENTION: if (!getPref(sharedPrefs, NotificationSettingsModel.PREF_MENTION_NOTIFICATION)) { return null; } return new GCMPostNotificationListener(); case FOLLOW_REQUEST: if (!getPref(sharedPrefs, NotificationSettingsModel.PREF_FOLLOWER_NOTIFICATION)) { return null; } return new GCMFollowRequestNotificationListener(); case FOLLOW_REQUEST_APPROVED: if (!getPref(sharedPrefs, NotificationSettingsModel.PREF_FOLLOWER_NOTIFICATION)) { return null; } return new GCMFollowRequestApprovedNotificationListener(); default: return null; } } protected boolean getPref(SharedPreferences sharedPrefs, String key) { return Boolean.valueOf(sharedPrefs.getBoolean(key, true)); } public static void registerOnPusher(String regId) { final Context context = ApplicationManager.getAppContext(); try { sendToPusher(context, regId); String currentRegId = Preferences.getPreference(context, Preferences.CURRENT_GCM_ID); if (currentRegId != null && !regId.equals(currentRegId)) { removeFromPusher(context, currentRegId); } int appVersion = VersionUtils.getVersionCode(context); Preferences.setPreference(context, Preferences.CURRENT_GCM_ID, regId); Preferences.setPreference(context, Preferences.APP_VERSION, String.valueOf(appVersion)); } catch (NameNotFoundException e) { Logger.error(TAG, "App Version code not found.", e); } } public static void sendToPusher(final Context context, String regId) { JSONObject settings = new JSONObject(); try { settings.put("type", "gcm"); settings.put("target", regId); settings.put("postMentionedMe", Boolean.TRUE.toString()); settings.put("postOnMyChannel", Boolean.TRUE.toString()); settings.put("followMyChannel", Boolean.TRUE.toString()); settings.put("postAfterMe", Boolean.TRUE.toString()); settings.put("postOnSubscribedChannel", Boolean.TRUE.toString()); } catch (JSONException e) { Logger.error(TAG, "Failure to register GCM settings.", e); return; } NotificationSettingsModel.getInstance().save( context, settings, new ModelCallback<JSONObject>() { @Override public void success(JSONObject response) { Logger.info(TAG, "Succesfully registered GCM settings."); } @Override public void error(Throwable throwable) { Logger.error(TAG, "Failure to register GCM settings.", throwable); } }); } public static void removeFromPusher(final Context context, String regId) { NotificationSettingsModel.getInstance().delete(context, new ModelCallback<Void>() { @Override public void success(Void response) { Logger.info(TAG, "Succesfully removed GCM settings."); } @Override public void error(Throwable throwable) { Logger.error(TAG, "Failed to remove GCM settings.", throwable); } }, regId); } }