From bcdea22667e7516ae910cee7249a99820ba2f833 Mon Sep 17 00:00:00 2001 From: Roman Savin Date: Tue, 16 Jun 2015 19:48:57 +0300 Subject: [PATCH 01/29] Update versions. --- opfpush-providers/adm/build.gradle | 2 +- opfpush-providers/gcm/build.gradle | 4 ++-- opfpush-providers/nokia/build.gradle | 2 +- opfpush/build.gradle | 2 +- samples/pushchat/build.gradle | 4 ++-- unity-plugin/build.gradle | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/opfpush-providers/adm/build.gradle b/opfpush-providers/adm/build.gradle index aa0f1585..47f204e3 100644 --- a/opfpush-providers/adm/build.gradle +++ b/opfpush-providers/adm/build.gradle @@ -21,7 +21,7 @@ android { defaultConfig { minSdkVersion 15 targetSdkVersion 22 - versionName "0.2.3" + versionName "0.2.4-SNAPSHOT" } } diff --git a/opfpush-providers/gcm/build.gradle b/opfpush-providers/gcm/build.gradle index 3b97d416..ee5d23ed 100644 --- a/opfpush-providers/gcm/build.gradle +++ b/opfpush-providers/gcm/build.gradle @@ -21,7 +21,7 @@ android { defaultConfig { minSdkVersion 15 targetSdkVersion 22 - versionName "0.2.3" + versionName "0.2.4-SNAPSHOT" } } @@ -33,7 +33,7 @@ dependencies { compile 'org.onepf:opfpush:0.2.3@aar' //noinspection NewerVersionAvailable - compile 'com.google.android.gms:play-services-gcm:7.3.0' + compile 'com.google.android.gms:play-services-gcm:7.5.0' provided 'com.android.support:support-annotations:19.1.0' //noinspection NewerVersionAvailable diff --git a/opfpush-providers/nokia/build.gradle b/opfpush-providers/nokia/build.gradle index bad36de7..ce0ccd59 100644 --- a/opfpush-providers/nokia/build.gradle +++ b/opfpush-providers/nokia/build.gradle @@ -21,7 +21,7 @@ android { defaultConfig { minSdkVersion 15 targetSdkVersion 22 - versionName "0.2.3" + versionName "0.2.4-SNAPSHOT" } } diff --git a/opfpush/build.gradle b/opfpush/build.gradle index f179dd00..9f32b414 100644 --- a/opfpush/build.gradle +++ b/opfpush/build.gradle @@ -32,7 +32,7 @@ android { defaultConfig { minSdkVersion 15 targetSdkVersion 22 - versionName "0.2.3" + versionName "0.2.4-SNAPSHOT" } } diff --git a/samples/pushchat/build.gradle b/samples/pushchat/build.gradle index 58497f37..b5f45b80 100644 --- a/samples/pushchat/build.gradle +++ b/samples/pushchat/build.gradle @@ -49,7 +49,7 @@ android { dependencies { //material - compile 'com.android.support:appcompat-v7:22.1.1' + compile 'com.android.support:appcompat-v7:22.2.0' compile 'com.melnykov:floatingactionbutton:1.3.0' //opfpush @@ -61,7 +61,7 @@ dependencies { //push providers dependencies provided 'com.amazon:amazon-device-messaging:1.0.1' - compile 'com.google.android.gms:play-services:7.3.0' + compile 'com.google.android.gms:play-services:7.5.0' compile 'com.nokia:push:1.0' //network diff --git a/unity-plugin/build.gradle b/unity-plugin/build.gradle index a3462efe..8a206d0f 100644 --- a/unity-plugin/build.gradle +++ b/unity-plugin/build.gradle @@ -21,7 +21,7 @@ android { defaultConfig { minSdkVersion 15 targetSdkVersion 22 - versionName "0.2.3-SNAPSHOT" + versionName "0.2.4-SNAPSHOT" } } From 413218cf8c4446c8ee606ef36c3937c93434af0d Mon Sep 17 00:00:00 2001 From: Roman Savin Date: Tue, 16 Jun 2015 19:49:33 +0300 Subject: [PATCH 02/29] Use InstanceID for gcm registration and unregistration. --- .../src/main/java/org/onepf/opfpush/gcm/GCMProvider.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMProvider.java b/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMProvider.java index b8fe6b23..19fd9263 100644 --- a/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMProvider.java +++ b/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMProvider.java @@ -27,6 +27,7 @@ import com.google.android.gms.common.GooglePlayServicesUtil; import com.google.android.gms.gcm.GoogleCloudMessaging; +import com.google.android.gms.iid.InstanceID; import org.onepf.opfpush.BasePushProvider; import org.onepf.opfpush.listener.CheckManifestHandler; import org.onepf.opfpush.model.AvailabilityResult; @@ -43,6 +44,7 @@ import java.util.concurrent.Executors; import static android.content.pm.PackageManager.PERMISSION_GRANTED; +import static com.google.android.gms.gcm.GoogleCloudMessaging.INSTANCE_ID_SCOPE; import static org.onepf.opfpush.gcm.GCMConstants.ACTION_REGISTRATION_CALLBACK; import static org.onepf.opfpush.gcm.GCMConstants.ACTION_UNREGISTRATION_CALLBACK; import static org.onepf.opfpush.gcm.GCMConstants.C2DM_ACTION_RECEIVE; @@ -198,7 +200,8 @@ public String toString() { return String.format(Locale.US, "%s (senderId: '%s')", PROVIDER_NAME, senderID); } - private void close() { + @SuppressWarnings("PMD.AvoidSynchronizedAtMethodLevel") + private synchronized void close() { OPFLog.logMethod(); if (registrationExecutor != null) { @@ -237,7 +240,7 @@ public void run() { try { final String registrationId = - GoogleCloudMessaging.getInstance(getContext()).register(senderID); + InstanceID.getInstance(getContext()).getToken(senderID, INSTANCE_ID_SCOPE); if (TextUtils.isEmpty(registrationId)) { OPFLog.w("Registration id is empty"); onAuthError(); @@ -309,7 +312,7 @@ public void run() { OPFLog.logMethod(); try { - GoogleCloudMessaging.getInstance(getContext()).unregister(); + InstanceID.getInstance(getContext()).deleteToken(senderID, INSTANCE_ID_SCOPE); close(); onUnregistrationSuccess(); From 2b374b22505194273cd9bb7b9da6b30fcb954d9a Mon Sep 17 00:00:00 2001 From: Roman Savin Date: Tue, 16 Jun 2015 20:41:13 +0300 Subject: [PATCH 03/29] Use GcmListenerService for messages receiving. --- opfpush-providers/gcm/README.md | 4 +- .../gcm/src/main/AndroidManifest.xml | 27 ++++++++++- .../gcm/GCMInstanceIDListenerService.java | 27 +++++++++++ .../onepf/opfpush/gcm/GCMMessageService.java | 48 +++++++++++++++++++ .../org/onepf/opfpush/gcm/GCMProvider.java | 4 +- ...iver.java => GCMRegistrationReceiver.java} | 6 +-- ...rvice.java => GCMRegistrationService.java} | 32 ++----------- samples/pushchat/src/main/AndroidManifest.xml | 6 +-- 8 files changed, 114 insertions(+), 40 deletions(-) create mode 100644 opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMInstanceIDListenerService.java create mode 100644 opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMMessageService.java rename opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/{GCMReceiver.java => GCMRegistrationReceiver.java} (87%) rename opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/{GCMService.java => GCMRegistrationService.java} (78%) diff --git a/opfpush-providers/gcm/README.md b/opfpush-providers/gcm/README.md index 6576e7a8..8836997b 100644 --- a/opfpush-providers/gcm/README.md +++ b/opfpush-providers/gcm/README.md @@ -49,7 +49,7 @@ also add the following receiver: ```xml @@ -71,7 +71,7 @@ If you use JAR dependency, you also must add to your application AndroidManifest + + + + + + + + + + + + + + + + + + + diff --git a/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMInstanceIDListenerService.java b/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMInstanceIDListenerService.java new file mode 100644 index 00000000..83b5378a --- /dev/null +++ b/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMInstanceIDListenerService.java @@ -0,0 +1,27 @@ +/* + * Copyright 2012-2015 One Platform Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onepf.opfpush.gcm; + +import com.google.android.gms.iid.InstanceIDListenerService; + +/** + * @author Roman Savin + * @since 16.06.2015 + */ +public class GCMInstanceIDListenerService extends InstanceIDListenerService { + //todo implement +} diff --git a/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMMessageService.java b/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMMessageService.java new file mode 100644 index 00000000..08ad9e77 --- /dev/null +++ b/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMMessageService.java @@ -0,0 +1,48 @@ +/* + * Copyright 2012-2015 One Platform Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onepf.opfpush.gcm; + +import android.os.Bundle; +import android.support.annotation.NonNull; +import com.google.android.gms.gcm.GcmListenerService; +import org.onepf.opfpush.OPFConstants; +import org.onepf.opfpush.OPFPush; +import org.onepf.opfutils.OPFLog; +import org.onepf.opfutils.OPFUtils; + +import static org.onepf.opfpush.gcm.GCMConstants.PROVIDER_NAME; + +/** + * @author Roman Savin + * @since 16.06.2015 + */ +public class GCMMessageService extends GcmListenerService { + + @Override + public void onMessageReceived(@NonNull final String from, @NonNull final Bundle data) { + //todo what is from parameter? + OPFLog.logMethod(from, OPFUtils.toString(data)); + OPFPush.getHelper().getReceivedMessageHandler().onMessage(PROVIDER_NAME, data); + } + + @Override + public void onDeletedMessages() { + OPFLog.logMethod(); + OPFPush.getHelper().getReceivedMessageHandler() + .onDeletedMessages(PROVIDER_NAME, OPFConstants.MESSAGES_COUNT_UNKNOWN); + } +} diff --git a/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMProvider.java b/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMProvider.java index 19fd9263..6c840572 100644 --- a/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMProvider.java +++ b/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMProvider.java @@ -108,14 +108,14 @@ public void checkManifest(@Nullable final CheckManifestHandler checkManifestHand final String c2dmPermission = context.getPackageName() + PERMISSION_C2D_MESSAGE_SUFFIX; CheckUtils.checkPermission(context, c2dmPermission, checkManifestHandler); - CheckUtils.checkService(context, new ComponentName(context, GCMService.class), checkManifestHandler); + CheckUtils.checkService(context, new ComponentName(context, GCMRegistrationService.class), checkManifestHandler); CheckUtils.checkService(context, new ComponentName(context, SendMessageService.class), checkManifestHandler); final Intent c2dmReceiveBroadcastIntent = new Intent(C2DM_ACTION_RECEIVE); final Intent registrationBroadcastIntent = new Intent(ACTION_REGISTRATION_CALLBACK); final Intent unregistrationBroadcastIntent = new Intent(ACTION_UNREGISTRATION_CALLBACK); - final String gcmReceiverName = GCMReceiver.class.getName(); + final String gcmReceiverName = GCMRegistrationReceiver.class.getName(); CheckUtils.checkReceiver(context, gcmReceiverName, c2dmReceiveBroadcastIntent, PERMISSION_SEND, checkManifestHandler); diff --git a/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMReceiver.java b/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMRegistrationReceiver.java similarity index 87% rename from opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMReceiver.java rename to opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMRegistrationReceiver.java index 39dd06ae..39345d83 100644 --- a/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMReceiver.java +++ b/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMRegistrationReceiver.java @@ -26,17 +26,17 @@ import org.onepf.opfutils.OPFUtils; /** - * Forwards the Google Cloud Messaging (GCM) messages to {@link GCMService}. + * Forwards the Google Cloud Messaging (GCM) messages to {@link GCMRegistrationService}. * * @author Roman Savin */ -public class GCMReceiver extends WakefulBroadcastReceiver { +public class GCMRegistrationReceiver extends WakefulBroadcastReceiver { @Override public void onReceive(@NonNull final Context context, @NonNull final Intent intent) { OPFLog.logMethod(context, OPFUtils.toString(intent)); - intent.setComponent(new ComponentName(context, GCMService.class)); + intent.setComponent(new ComponentName(context, GCMRegistrationService.class)); startWakefulService(context, intent); if (isOrderedBroadcast()) { setResultCode(Activity.RESULT_OK); diff --git a/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMService.java b/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMRegistrationService.java similarity index 78% rename from opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMService.java rename to opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMRegistrationService.java index 48c4092d..9786e358 100644 --- a/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMService.java +++ b/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMRegistrationService.java @@ -20,10 +20,6 @@ import android.content.Intent; import android.support.annotation.NonNull; import android.support.annotation.Nullable; - -import com.google.android.gms.gcm.GoogleCloudMessaging; - -import org.onepf.opfpush.OPFConstants; import org.onepf.opfpush.OPFPush; import org.onepf.opfpush.model.PushError; import org.onepf.opfpush.model.RecoverablePushError; @@ -38,17 +34,17 @@ /** * This {@link IntentService} does the actual handling of the GCM message. - * {@link org.onepf.opfpush.gcm.GCMReceiver} (a {@code WakefulBroadcastReceiver}) holds a + * {@link GCMRegistrationReceiver} (a {@code WakefulBroadcastReceiver}) holds a * partial wake lock for this service while the service does its work. When the * service is finished, it calls {@code completeWakefulIntent()} to release the * wake lock. * * @author Roman Savin */ -public class GCMService extends IntentService { +public class GCMRegistrationService extends IntentService { - public GCMService() { - super("GCMService"); + public GCMRegistrationService() { + super("GCMRegistrationService"); } @Override @@ -70,26 +66,8 @@ protected void onHandleIntent(final Intent intent) { } else { onUnregistered(intent.getStringExtra(GCMConstants.EXTRA_REGISTRATION_ID)); } - } else if (intent.getExtras() != null) { - final String messageType = GoogleCloudMessaging.getInstance(this).getMessageType(intent); - if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED.equals(messageType)) { - onDeletedMessages(); - } else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType)) { - onMessage(intent); - } } - GCMReceiver.completeWakefulIntent(intent); - } - - private void onMessage(@NonNull final Intent intent) { - OPFLog.logMethod(OPFUtils.toString(intent)); - OPFPush.getHelper().getReceivedMessageHandler().onMessage(PROVIDER_NAME, intent.getExtras()); - } - - private void onDeletedMessages() { - OPFLog.logMethod(); - OPFPush.getHelper().getReceivedMessageHandler() - .onDeletedMessages(PROVIDER_NAME, OPFConstants.MESSAGES_COUNT_UNKNOWN); + GCMRegistrationReceiver.completeWakefulIntent(intent); } private void onRegistered(@NonNull final String registrationId) { diff --git a/samples/pushchat/src/main/AndroidManifest.xml b/samples/pushchat/src/main/AndroidManifest.xml index e1c8dac7..9f391de7 100644 --- a/samples/pushchat/src/main/AndroidManifest.xml +++ b/samples/pushchat/src/main/AndroidManifest.xml @@ -56,17 +56,13 @@ - - - - From 9a56099884d4abd865ce67b92febafafedcfedca Mon Sep 17 00:00:00 2001 From: Roman Savin Date: Wed, 17 Jun 2015 13:39:42 +0300 Subject: [PATCH 04/29] Update versions. Add changing dependencies. --- opfpush-providers/adm/build.gradle | 6 ++++-- opfpush-providers/gcm/build.gradle | 6 ++++-- opfpush-providers/nokia/build.gradle | 6 ++++-- opfpush/build.gradle | 2 +- samples/pushchat/build.gradle | 16 ++++++++++++---- unity-plugin/build.gradle | 18 +++++++++++++----- 6 files changed, 38 insertions(+), 16 deletions(-) diff --git a/opfpush-providers/adm/build.gradle b/opfpush-providers/adm/build.gradle index aa0f1585..a9484300 100644 --- a/opfpush-providers/adm/build.gradle +++ b/opfpush-providers/adm/build.gradle @@ -21,7 +21,7 @@ android { defaultConfig { minSdkVersion 15 targetSdkVersion 22 - versionName "0.2.3" + versionName "0.2.4-SNAPSHOT" } } @@ -31,7 +31,9 @@ dependencies { androidTestCompile 'junit:junit:4.12' androidTestCompile 'org.robolectric:robolectric:2.4' - compile 'org.onepf:opfpush:0.2.3@aar' + compile ('org.onepf:opfpush:0.2.+@aar') { + changing = true + } provided 'com.amazon:amazon-device-messaging:1.0.1' provided 'com.android.support:support-annotations:19.1.0' diff --git a/opfpush-providers/gcm/build.gradle b/opfpush-providers/gcm/build.gradle index 82a56b23..8398cef4 100644 --- a/opfpush-providers/gcm/build.gradle +++ b/opfpush-providers/gcm/build.gradle @@ -21,7 +21,7 @@ android { defaultConfig { minSdkVersion 15 targetSdkVersion 22 - versionName "0.2.3" + versionName "0.2.4-SNAPSHOT" } } @@ -31,7 +31,9 @@ dependencies { androidTestCompile 'junit:junit:4.12' androidTestCompile 'org.robolectric:robolectric:2.4' - compile 'org.onepf:opfpush:0.2.3@aar' + compile ('org.onepf:opfpush:0.2.+@aar') { + changing = true + } //noinspection ObsoleteGradleDependency compile 'com.google.android.gms:play-services-gcm:7.3.0' diff --git a/opfpush-providers/nokia/build.gradle b/opfpush-providers/nokia/build.gradle index bad36de7..51c7bc69 100644 --- a/opfpush-providers/nokia/build.gradle +++ b/opfpush-providers/nokia/build.gradle @@ -21,12 +21,14 @@ android { defaultConfig { minSdkVersion 15 targetSdkVersion 22 - versionName "0.2.3" + versionName "0.2.4-SNAPSHOT" } } dependencies { - compile 'org.onepf:opfpush:0.2.3@aar' + compile ('org.onepf:opfpush:0.2.+@aar') { + changing = true + } compile 'com.nokia:push:1.0' provided 'com.android.support:support-annotations:19.1.0' diff --git a/opfpush/build.gradle b/opfpush/build.gradle index f179dd00..9f32b414 100644 --- a/opfpush/build.gradle +++ b/opfpush/build.gradle @@ -32,7 +32,7 @@ android { defaultConfig { minSdkVersion 15 targetSdkVersion 22 - versionName "0.2.3" + versionName "0.2.4-SNAPSHOT" } } diff --git a/samples/pushchat/build.gradle b/samples/pushchat/build.gradle index 3f9e4e50..dd185f02 100644 --- a/samples/pushchat/build.gradle +++ b/samples/pushchat/build.gradle @@ -53,10 +53,18 @@ dependencies { //opfpush compile 'org.onepf:opfutils:0.1.22' - compile 'org.onepf:opfpush:0.2.3@aar' - compile 'org.onepf:opfpush-adm:0.2.3@aar' - compile 'org.onepf:opfpush-gcm:0.2.3@aar' - compile 'org.onepf:opfpush-nokia:0.2.3@aar' + compile('org.onepf:opfpush:0.2.+@aar') { + changing = true + } + compile('org.onepf:opfpush-adm:0.2.+@aar') { + changing = true + } + compile('org.onepf:opfpush-gcm:0.2.+@aar') { + changing = true + } + compile('org.onepf:opfpush-nokia:0.2.+@aar') { + changing = true + } //push providers dependencies provided 'com.amazon:amazon-device-messaging:1.0.1' diff --git a/unity-plugin/build.gradle b/unity-plugin/build.gradle index a3462efe..62ad96cb 100644 --- a/unity-plugin/build.gradle +++ b/unity-plugin/build.gradle @@ -21,7 +21,7 @@ android { defaultConfig { minSdkVersion 15 targetSdkVersion 22 - versionName "0.2.3-SNAPSHOT" + versionName "0.2.4-SNAPSHOT" } } @@ -30,8 +30,16 @@ dependencies { //opfpush compile 'org.onepf:opfutils:0.1.22' - compile 'org.onepf:opfpush:0.2.3@aar' - compile 'org.onepf:opfpush-adm:0.2.3@aar' - compile 'org.onepf:opfpush-gcm:0.2.3@aar' - compile 'org.onepf:opfpush-nokia:0.2.3@aar' + compile('org.onepf:opfpush:0.2.+@aar') { + changing = true + } + compile('org.onepf:opfpush-adm:0.2.+@aar') { + changing = true + } + compile('org.onepf:opfpush-gcm:0.2.+@aar') { + changing = true + } + compile('org.onepf:opfpush-nokia:0.2.+@aar') { + changing = true + } } \ No newline at end of file From f4b53fc0eed063f168fac4bccdfb6bdaee6a2767 Mon Sep 17 00:00:00 2001 From: Roman Savin Date: Wed, 17 Jun 2015 16:41:04 +0300 Subject: [PATCH 05/29] Remove GCM registration receiver and provider. GCMRegistrationReceiver and GCMRegistrationProvider are useless so it has removed. Registration and unregistration events are sent directly to ReceivedMessageHandler. --- .../gcm/src/main/AndroidManifest.xml | 15 +-- .../java/org/onepf/opfpush/gcm/GCMAction.java | 34 ------ .../org/onepf/opfpush/gcm/GCMConstants.java | 3 - .../org/onepf/opfpush/gcm/GCMProvider.java | 83 ++++++------- .../opfpush/gcm/GCMRegistrationReceiver.java | 45 ------- .../opfpush/gcm/GCMRegistrationService.java | 110 ------------------ ...GCMMessageService.java => GCMService.java} | 3 +- samples/pushchat/proguard-project.txt | 5 + 8 files changed, 41 insertions(+), 257 deletions(-) delete mode 100644 opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMAction.java delete mode 100644 opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMRegistrationReceiver.java delete mode 100644 opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMRegistrationService.java rename opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/{GCMMessageService.java => GCMService.java} (93%) diff --git a/opfpush-providers/gcm/src/main/AndroidManifest.xml b/opfpush-providers/gcm/src/main/AndroidManifest.xml index f7d2bc31..e8c08e0c 100644 --- a/opfpush-providers/gcm/src/main/AndroidManifest.xml +++ b/opfpush-providers/gcm/src/main/AndroidManifest.xml @@ -20,21 +20,8 @@ - - - - - - - - - diff --git a/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMAction.java b/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMAction.java deleted file mode 100644 index 60fabdc1..00000000 --- a/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMAction.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2012-2015 One Platform Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onepf.opfpush.gcm; - -import android.support.annotation.StringDef; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * @author Kirill Rozov - * @since 24.09.14. - */ -@Retention(RetentionPolicy.SOURCE) -@StringDef({ - GCMConstants.ACTION_REGISTRATION_CALLBACK, - GCMConstants.ACTION_UNREGISTRATION_CALLBACK -}) -@interface GCMAction { -} diff --git a/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMConstants.java b/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMConstants.java index be77dd8f..ef31b16a 100644 --- a/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMConstants.java +++ b/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMConstants.java @@ -32,9 +32,6 @@ public final class GCMConstants { */ public static final String PROVIDER_NAME = "Google Cloud Messaging"; - static final String ACTION_REGISTRATION_CALLBACK = BuildConfig.APPLICATION_ID + ".intent.REGISTRATION"; - static final String ACTION_UNREGISTRATION_CALLBACK = BuildConfig.APPLICATION_ID + ".intent.UNREGISTRATION"; - static final String C2DM_ACTION_RECEIVE = "com.google.android.c2dm.intent.RECEIVE"; static final String EXTRA_ERROR_ID = "error_id"; diff --git a/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMProvider.java b/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMProvider.java index 6c840572..15bd0706 100644 --- a/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMProvider.java +++ b/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMProvider.java @@ -22,20 +22,22 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.text.TextUtils; - import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GooglePlayServicesUtil; +import com.google.android.gms.gcm.GcmReceiver; import com.google.android.gms.gcm.GoogleCloudMessaging; - import com.google.android.gms.iid.InstanceID; import org.onepf.opfpush.BasePushProvider; +import org.onepf.opfpush.OPFPush; import org.onepf.opfpush.listener.CheckManifestHandler; import org.onepf.opfpush.model.AvailabilityResult; import org.onepf.opfpush.model.Message; +import org.onepf.opfpush.model.PushError; +import org.onepf.opfpush.model.RecoverablePushError; +import org.onepf.opfpush.model.UnrecoverablePushError; import org.onepf.opfpush.pushprovider.SenderPushProvider; import org.onepf.opfpush.utils.CheckUtils; import org.onepf.opfutils.OPFLog; -import org.onepf.opfutils.OPFUtils; import org.onepf.opfutils.exception.WrongThreadException; import java.io.IOException; @@ -45,17 +47,19 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static com.google.android.gms.gcm.GoogleCloudMessaging.INSTANCE_ID_SCOPE; -import static org.onepf.opfpush.gcm.GCMConstants.ACTION_REGISTRATION_CALLBACK; -import static org.onepf.opfpush.gcm.GCMConstants.ACTION_UNREGISTRATION_CALLBACK; import static org.onepf.opfpush.gcm.GCMConstants.C2DM_ACTION_RECEIVE; +import static org.onepf.opfpush.gcm.GCMConstants.ERROR_AUTHENTICATION_FAILED; +import static org.onepf.opfpush.gcm.GCMConstants.ERROR_SERVICE_NOT_AVAILABLE; import static org.onepf.opfpush.gcm.GCMConstants.GOOGLE_CLOUD_MESSAGING_CLASS_NAME; import static org.onepf.opfpush.gcm.GCMConstants.GOOGLE_PLAY_APP_PACKAGE; import static org.onepf.opfpush.gcm.GCMConstants.GOOGLE_SERVICES_FRAMEWORK_PACKAGE; import static org.onepf.opfpush.gcm.GCMConstants.MESSAGES_TO_SUFFIX; import static org.onepf.opfpush.gcm.GCMConstants.PERMISSION_C2D_MESSAGE_SUFFIX; import static org.onepf.opfpush.gcm.GCMConstants.PERMISSION_RECEIVE; -import static org.onepf.opfpush.gcm.GCMConstants.PERMISSION_SEND; import static org.onepf.opfpush.gcm.GCMConstants.PROVIDER_NAME; +import static org.onepf.opfpush.model.RecoverablePushError.Type.SERVICE_NOT_AVAILABLE; +import static org.onepf.opfpush.model.UnrecoverablePushError.Type.AUTHENTICATION_FAILED; +import static org.onepf.opfpush.model.UnrecoverablePushError.Type.PROVIDER_SPECIFIC_ERROR; /** * Google Cloud Messaging push provider implementation. @@ -108,21 +112,11 @@ public void checkManifest(@Nullable final CheckManifestHandler checkManifestHand final String c2dmPermission = context.getPackageName() + PERMISSION_C2D_MESSAGE_SUFFIX; CheckUtils.checkPermission(context, c2dmPermission, checkManifestHandler); - CheckUtils.checkService(context, new ComponentName(context, GCMRegistrationService.class), checkManifestHandler); CheckUtils.checkService(context, new ComponentName(context, SendMessageService.class), checkManifestHandler); + CheckUtils.checkService(context, new ComponentName(context, GCMService.class), checkManifestHandler); + CheckUtils.checkService(context, new ComponentName(context, GCMInstanceIDListenerService.class), checkManifestHandler); - final Intent c2dmReceiveBroadcastIntent = new Intent(C2DM_ACTION_RECEIVE); - final Intent registrationBroadcastIntent = new Intent(ACTION_REGISTRATION_CALLBACK); - final Intent unregistrationBroadcastIntent = new Intent(ACTION_UNREGISTRATION_CALLBACK); - - final String gcmReceiverName = GCMRegistrationReceiver.class.getName(); - - CheckUtils.checkReceiver(context, gcmReceiverName, c2dmReceiveBroadcastIntent, - PERMISSION_SEND, checkManifestHandler); - CheckUtils.checkReceiver(context, gcmReceiverName, registrationBroadcastIntent, - PERMISSION_SEND, checkManifestHandler); - CheckUtils.checkReceiver(context, gcmReceiverName, unregistrationBroadcastIntent, - PERMISSION_SEND, checkManifestHandler); + CheckUtils.checkReceiver(context, GcmReceiver.class.getName(), new Intent(C2DM_ACTION_RECEIVE), checkManifestHandler); } @NonNull @@ -176,6 +170,7 @@ public void onRegistrationInvalid() { @Override public void onUnavailable() { OPFLog.logMethod(); + preferencesProvider.reset(); close(); } @@ -211,7 +206,6 @@ private synchronized void close() { registrationExecutor = null; } - preferencesProvider.reset(); GoogleCloudMessaging.getInstance(getContext()).close(); } @@ -267,33 +261,23 @@ public void run() { private void onServicesNotAvailable() { OPFLog.logMethod(); - - final Intent intent = new Intent(GCMConstants.ACTION_REGISTRATION_CALLBACK); - intent.putExtra(GCMConstants.EXTRA_ERROR_ID, GCMConstants.ERROR_SERVICE_NOT_AVAILABLE); - getContext().sendBroadcast(intent); + onError(ERROR_SERVICE_NOT_AVAILABLE); } private void onRegistrationSuccess(@NonNull final String registrationId) { OPFLog.logMethod(registrationId); preferencesProvider.saveRegistrationId(registrationId); - - final Intent intent = new Intent(GCMConstants.ACTION_REGISTRATION_CALLBACK); - intent.putExtra(GCMConstants.EXTRA_REGISTRATION_ID, registrationId); - - OPFLog.d("Send broadcast intent : " + OPFUtils.toString(intent)); - getContext().sendBroadcast(intent); + OPFPush.getHelper().getReceivedMessageHandler().onRegistered(PROVIDER_NAME, registrationId); } private void onAuthError() { OPFLog.logMethod(); - onError(GCMConstants.ERROR_AUTHENTICATION_FAILED); + onError(ERROR_AUTHENTICATION_FAILED); } private void onError(@NonNull final String errorId) { OPFLog.logMethod(errorId); - final Intent intent = new Intent(GCMConstants.ACTION_REGISTRATION_CALLBACK); - intent.putExtra(GCMConstants.EXTRA_ERROR_ID, errorId); - getContext().sendBroadcast(intent); + OPFPush.getHelper().getReceivedMessageHandler().onRegistrationError(PROVIDER_NAME, convertError(errorId)); } } @@ -313,8 +297,7 @@ public void run() { try { InstanceID.getInstance(getContext()).deleteToken(senderID, INSTANCE_ID_SCOPE); - close(); - + preferencesProvider.reset(); onUnregistrationSuccess(); } catch (IOException e) { OPFLog.i("Error while unregister GCM.", e); @@ -331,31 +314,33 @@ public void run() { break; } } + close(); } private void onServicesNotAvailable() { OPFLog.logMethod(); - - final Intent intent = new Intent(GCMConstants.ACTION_UNREGISTRATION_CALLBACK); - intent.putExtra(GCMConstants.EXTRA_ERROR_ID, GCMConstants.ERROR_SERVICE_NOT_AVAILABLE); - getContext().sendBroadcast(intent); + onError(ERROR_SERVICE_NOT_AVAILABLE); } private void onUnregistrationSuccess() { OPFLog.logMethod(); - - final Intent intent = new Intent(GCMConstants.ACTION_UNREGISTRATION_CALLBACK); - intent.putExtra(GCMConstants.EXTRA_REGISTRATION_ID, oldRegistrationId); - - OPFLog.d("Send broadcast intent : " + OPFUtils.toString(intent)); - getContext().sendBroadcast(intent); + OPFPush.getHelper().getReceivedMessageHandler().onUnregistered(PROVIDER_NAME, oldRegistrationId); } private void onError(@NonNull final String errorId) { OPFLog.logMethod(errorId); - final Intent intent = new Intent(GCMConstants.ACTION_UNREGISTRATION_CALLBACK); - intent.putExtra(GCMConstants.EXTRA_ERROR_ID, errorId); - getContext().sendBroadcast(intent); + OPFPush.getHelper().getReceivedMessageHandler().onUnregistrationError(PROVIDER_NAME, convertError(errorId)); + } + } + + private PushError convertError(@NonNull final String errorId) { + switch (errorId) { + case ERROR_SERVICE_NOT_AVAILABLE: + return new RecoverablePushError(SERVICE_NOT_AVAILABLE, PROVIDER_NAME, errorId); + case ERROR_AUTHENTICATION_FAILED: + return new UnrecoverablePushError(AUTHENTICATION_FAILED, PROVIDER_NAME, errorId); + default: + return new UnrecoverablePushError(PROVIDER_SPECIFIC_ERROR, PROVIDER_NAME, errorId); } } } diff --git a/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMRegistrationReceiver.java b/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMRegistrationReceiver.java deleted file mode 100644 index 39345d83..00000000 --- a/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMRegistrationReceiver.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2012-2015 One Platform Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onepf.opfpush.gcm; - -import android.app.Activity; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.support.annotation.NonNull; - -import org.onepf.opfutils.OPFLog; -import org.onepf.opfutils.OPFUtils; - -/** - * Forwards the Google Cloud Messaging (GCM) messages to {@link GCMRegistrationService}. - * - * @author Roman Savin - */ -public class GCMRegistrationReceiver extends WakefulBroadcastReceiver { - - @Override - public void onReceive(@NonNull final Context context, @NonNull final Intent intent) { - OPFLog.logMethod(context, OPFUtils.toString(intent)); - - intent.setComponent(new ComponentName(context, GCMRegistrationService.class)); - startWakefulService(context, intent); - if (isOrderedBroadcast()) { - setResultCode(Activity.RESULT_OK); - } - } -} diff --git a/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMRegistrationService.java b/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMRegistrationService.java deleted file mode 100644 index 9786e358..00000000 --- a/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMRegistrationService.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2012-2015 One Platform Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onepf.opfpush.gcm; - -import android.app.IntentService; -import android.content.Intent; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import org.onepf.opfpush.OPFPush; -import org.onepf.opfpush.model.PushError; -import org.onepf.opfpush.model.RecoverablePushError; -import org.onepf.opfpush.model.UnrecoverablePushError; -import org.onepf.opfutils.OPFLog; -import org.onepf.opfutils.OPFUtils; - -import static org.onepf.opfpush.gcm.GCMConstants.PROVIDER_NAME; -import static org.onepf.opfpush.model.RecoverablePushError.Type.SERVICE_NOT_AVAILABLE; -import static org.onepf.opfpush.model.UnrecoverablePushError.Type.AUTHENTICATION_FAILED; -import static org.onepf.opfpush.model.UnrecoverablePushError.Type.PROVIDER_SPECIFIC_ERROR; - -/** - * This {@link IntentService} does the actual handling of the GCM message. - * {@link GCMRegistrationReceiver} (a {@code WakefulBroadcastReceiver}) holds a - * partial wake lock for this service while the service does its work. When the - * service is finished, it calls {@code completeWakefulIntent()} to release the - * wake lock. - * - * @author Roman Savin - */ -public class GCMRegistrationService extends IntentService { - - public GCMRegistrationService() { - super("GCMRegistrationService"); - } - - @Override - protected void onHandleIntent(final Intent intent) { - OPFLog.logMethod(OPFUtils.toString(intent)); - - @GCMAction String action = intent.getAction(); - if (GCMConstants.ACTION_REGISTRATION_CALLBACK.equals(action)) { - if (intent.hasExtra(GCMConstants.EXTRA_ERROR_ID)) { - final String errorId = intent.getStringExtra(GCMConstants.EXTRA_ERROR_ID); - onRegistrationError(errorId); - } else { - onRegistered(intent.getStringExtra(GCMConstants.EXTRA_REGISTRATION_ID)); - } - } else if (GCMConstants.ACTION_UNREGISTRATION_CALLBACK.equals(action)) { - if (intent.hasExtra(GCMConstants.EXTRA_ERROR_ID)) { - final String errorId = intent.getStringExtra(GCMConstants.EXTRA_ERROR_ID); - onUnregistrationError(errorId); - } else { - onUnregistered(intent.getStringExtra(GCMConstants.EXTRA_REGISTRATION_ID)); - } - } - GCMRegistrationReceiver.completeWakefulIntent(intent); - } - - private void onRegistered(@NonNull final String registrationId) { - OPFLog.logMethod(registrationId); - OPFPush.getHelper().getReceivedMessageHandler().onRegistered(PROVIDER_NAME, registrationId); - } - - private void onUnregistered(@Nullable final String oldRegistrationId) { - OPFLog.logMethod(oldRegistrationId); - OPFPush.getHelper().getReceivedMessageHandler().onUnregistered(PROVIDER_NAME, oldRegistrationId); - } - - private void onRegistrationError(@NonNull final String errorId) { - OPFLog.logMethod(errorId); - final PushError error = convertError(errorId); - OPFLog.d("Converted error : " + error); - - OPFPush.getHelper().getReceivedMessageHandler().onRegistrationError(PROVIDER_NAME, error); - } - - private void onUnregistrationError(@NonNull final String errorId) { - OPFLog.logMethod(errorId); - final PushError error = convertError(errorId); - OPFLog.d("Converted error : " + error); - - OPFPush.getHelper().getReceivedMessageHandler() - .onUnregistrationError(PROVIDER_NAME, error); - } - - private PushError convertError(@NonNull final String errorId) { - switch (errorId) { - case GCMConstants.ERROR_SERVICE_NOT_AVAILABLE: - return new RecoverablePushError(SERVICE_NOT_AVAILABLE, PROVIDER_NAME, errorId); - case GCMConstants.ERROR_AUTHENTICATION_FAILED: - return new UnrecoverablePushError(AUTHENTICATION_FAILED, PROVIDER_NAME, errorId); - default: - return new UnrecoverablePushError(PROVIDER_SPECIFIC_ERROR, PROVIDER_NAME, errorId); - } - } -} diff --git a/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMMessageService.java b/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMService.java similarity index 93% rename from opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMMessageService.java rename to opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMService.java index 08ad9e77..54d92692 100644 --- a/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMMessageService.java +++ b/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMService.java @@ -30,11 +30,10 @@ * @author Roman Savin * @since 16.06.2015 */ -public class GCMMessageService extends GcmListenerService { +public class GCMService extends GcmListenerService { @Override public void onMessageReceived(@NonNull final String from, @NonNull final Bundle data) { - //todo what is from parameter? OPFLog.logMethod(from, OPFUtils.toString(data)); OPFPush.getHelper().getReceivedMessageHandler().onMessage(PROVIDER_NAME, data); } diff --git a/samples/pushchat/proguard-project.txt b/samples/pushchat/proguard-project.txt index 8759330e..75ecca96 100644 --- a/samples/pushchat/proguard-project.txt +++ b/samples/pushchat/proguard-project.txt @@ -30,6 +30,11 @@ #appcompat -dontwarn android.view.accessibility.AccessibilityNodeInfo -dontwarn android.media.session.MediaSession +-dontwarn android.support.v4.app.DialogFragment +-dontwarn android.support.v4.app.FragmentTransaction +-dontwarn android.support.v4.view.ViewCompat +-dontwarn android.support.v4.widget.DrawerLayout +-dontwarn android.support.v7.media.** #retrofit -keepattributes Signature From f2d7d9ef0112561ccb4e6bde79881b77548286c4 Mon Sep 17 00:00:00 2001 From: Roman Savin Date: Tue, 23 Jun 2015 20:03:10 +0300 Subject: [PATCH 06/29] Remove unused gcm constants. --- .../src/main/java/org/onepf/opfpush/gcm/GCMConstants.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMConstants.java b/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMConstants.java index ef31b16a..c0f81328 100644 --- a/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMConstants.java +++ b/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMConstants.java @@ -34,17 +34,11 @@ public final class GCMConstants { static final String C2DM_ACTION_RECEIVE = "com.google.android.c2dm.intent.RECEIVE"; - static final String EXTRA_ERROR_ID = "error_id"; - static final String EXTRA_REGISTRATION_ID = "registration_id"; static final String ERROR_AUTHENTICATION_FAILED = "AUTHENTICATION_FAILED"; static final String ERROR_SERVICE_NOT_AVAILABLE = GoogleCloudMessaging.ERROR_SERVICE_NOT_AVAILABLE; static final String GOOGLE_PLAY_APP_PACKAGE = "com.android.vending"; - static final String GOOGLE_ACCOUNT_TYPE = "com.google"; - static final String ANDROID_RELEASE_4_0_4 = "4.0.4"; - - static final String PERMISSION_SEND = "com.google.android.c2dm.permission.SEND"; static final String PERMISSION_RECEIVE = "com.google.android.c2dm.permission.RECEIVE"; static final String PERMISSION_C2D_MESSAGE_SUFFIX = ".permission.C2D_MESSAGE"; static final String GOOGLE_CLOUD_MESSAGING_CLASS_NAME = "com.google.android.gms.gcm.GoogleCloudMessaging"; From 87fd8f39e39d0a82e98253544ec41df96ce58993 Mon Sep 17 00:00:00 2001 From: Roman Savin Date: Wed, 24 Jun 2015 12:00:08 +0300 Subject: [PATCH 07/29] Add NotificationMaker. Add notification maker for implicit notifications. --- .../org/onepf/opfpush/adm/ADMProvider.java | 18 ++ .../onepf/opfpush/adm/ADMProviderImpl.java | 11 +- .../onepf/opfpush/adm/ADMProviderStub.java | 21 +- .../org/onepf/opfpush/gcm/GCMProvider.java | 10 +- .../nokia/NokiaNotificationsProvider.java | 19 ++ .../nokia/NokiaNotificationsProviderImpl.java | 8 + .../nokia/NokiaNotificationsProviderStub.java | 19 ++ .../org/onepf/opfpush/BasePushProvider.java | 20 ++ .../org/onepf/opfpush/OPFPushHelperImpl.java | 9 +- .../opfpush/model/NotificationPayload.java | 188 ++++++++++++++++++ .../notification/NotificationMaker.java | 34 ++++ .../notification/NotificationPreparer.java | 34 ++++ .../notification/OPFNotificationMaker.java | 58 ++++++ .../notification/OPFNotificationPreparer.java | 71 +++++++ .../opfpush/pushprovider/PushProvider.java | 5 + .../opfpush/utils/NotificationUtils.java | 153 ++++++++++++++ .../onepf/opfpush/mock/MockPushProvider.java | 8 + 17 files changed, 678 insertions(+), 8 deletions(-) create mode 100644 opfpush/src/main/java/org/onepf/opfpush/model/NotificationPayload.java create mode 100644 opfpush/src/main/java/org/onepf/opfpush/notification/NotificationMaker.java create mode 100644 opfpush/src/main/java/org/onepf/opfpush/notification/NotificationPreparer.java create mode 100644 opfpush/src/main/java/org/onepf/opfpush/notification/OPFNotificationMaker.java create mode 100644 opfpush/src/main/java/org/onepf/opfpush/notification/OPFNotificationPreparer.java create mode 100644 opfpush/src/main/java/org/onepf/opfpush/utils/NotificationUtils.java diff --git a/opfpush-providers/adm/src/main/java/org/onepf/opfpush/adm/ADMProvider.java b/opfpush-providers/adm/src/main/java/org/onepf/opfpush/adm/ADMProvider.java index 0f4de5b2..53c08df9 100644 --- a/opfpush-providers/adm/src/main/java/org/onepf/opfpush/adm/ADMProvider.java +++ b/opfpush-providers/adm/src/main/java/org/onepf/opfpush/adm/ADMProvider.java @@ -23,6 +23,7 @@ import org.onepf.opfpush.listener.CheckManifestHandler; import org.onepf.opfpush.model.AvailabilityResult; +import org.onepf.opfpush.notification.NotificationMaker; import org.onepf.opfpush.pushprovider.PushProvider; import org.onepf.opfutils.OPFLog; @@ -51,6 +52,17 @@ public ADMProvider(@NonNull final Context context) { } } + public ADMProvider(@NonNull final Context context, + @NonNull final NotificationMaker notificationMaker) { + if (Build.MANUFACTURER.equals(AMAZON_MANUFACTURER)) { + OPFLog.d("It's an Amazon device."); + provider = new ADMProviderImpl(context.getApplicationContext(), notificationMaker); + } else { + OPFLog.d("It's no an Amazon device."); + provider = new ADMProviderStub(); + } + } + @Override public void register() { provider.register(); @@ -90,6 +102,12 @@ public String getHostAppPackage() { return provider.getHostAppPackage(); } + @NonNull + @Override + public NotificationMaker getNotificationMaker() { + return provider.getNotificationMaker(); + } + @Override public void checkManifest(@Nullable final CheckManifestHandler checkManifestHandler) { provider.checkManifest(checkManifestHandler); diff --git a/opfpush-providers/adm/src/main/java/org/onepf/opfpush/adm/ADMProviderImpl.java b/opfpush-providers/adm/src/main/java/org/onepf/opfpush/adm/ADMProviderImpl.java index da5589c6..3ea372f9 100644 --- a/opfpush-providers/adm/src/main/java/org/onepf/opfpush/adm/ADMProviderImpl.java +++ b/opfpush-providers/adm/src/main/java/org/onepf/opfpush/adm/ADMProviderImpl.java @@ -31,6 +31,7 @@ import org.onepf.opfpush.BasePushProvider; import org.onepf.opfpush.listener.CheckManifestHandler; import org.onepf.opfpush.model.AvailabilityResult; +import org.onepf.opfpush.notification.NotificationMaker; import org.onepf.opfpush.utils.CheckUtils; import org.onepf.opfutils.OPFLog; @@ -52,15 +53,17 @@ class ADMProviderImpl extends BasePushProvider { @NonNull - private final ADM adm; + private final ADM adm = new ADM(getContext().getApplicationContext()); @NonNull - private final PreferencesProvider preferencesProvider; + private final PreferencesProvider preferencesProvider = PreferencesProvider.getInstance(getContext()); public ADMProviderImpl(@NonNull final Context context) { super(context, PROVIDER_NAME, KINDLE_STORE_APP_PACKAGE); - adm = new ADM(context.getApplicationContext()); - preferencesProvider = PreferencesProvider.getInstance(getContext()); + } + + public ADMProviderImpl(@NonNull final Context context, @NonNull final NotificationMaker notificationMaker) { + super(context, PROVIDER_NAME, KINDLE_STORE_APP_PACKAGE, notificationMaker); } @Override diff --git a/opfpush-providers/adm/src/main/java/org/onepf/opfpush/adm/ADMProviderStub.java b/opfpush-providers/adm/src/main/java/org/onepf/opfpush/adm/ADMProviderStub.java index 879bde25..5f9d9009 100644 --- a/opfpush-providers/adm/src/main/java/org/onepf/opfpush/adm/ADMProviderStub.java +++ b/opfpush-providers/adm/src/main/java/org/onepf/opfpush/adm/ADMProviderStub.java @@ -16,11 +16,13 @@ package org.onepf.opfpush.adm; +import android.content.Context; +import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; - import org.onepf.opfpush.listener.CheckManifestHandler; import org.onepf.opfpush.model.AvailabilityResult; +import org.onepf.opfpush.notification.NotificationMaker; import org.onepf.opfpush.pushprovider.PushProvider; import org.onepf.opfutils.OPFLog; @@ -78,6 +80,23 @@ public String getHostAppPackage() { return null; } + @NonNull + @Override + public NotificationMaker getNotificationMaker() { + OPFLog.logMethod(); + return new NotificationMaker() { + @Override + public boolean needShowNotification(@NonNull Bundle bundle) { + return false; + } + + @Override + public void showNotification(@NonNull Context context, @NonNull Bundle bundle) { + //nothing + } + }; + } + @Override public void checkManifest(@Nullable final CheckManifestHandler checkManifestHandler) { OPFLog.logMethod(); diff --git a/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMProvider.java b/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMProvider.java index 15bd0706..161570fb 100644 --- a/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMProvider.java +++ b/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMProvider.java @@ -35,6 +35,7 @@ import org.onepf.opfpush.model.PushError; import org.onepf.opfpush.model.RecoverablePushError; import org.onepf.opfpush.model.UnrecoverablePushError; +import org.onepf.opfpush.notification.NotificationMaker; import org.onepf.opfpush.pushprovider.SenderPushProvider; import org.onepf.opfpush.utils.CheckUtils; import org.onepf.opfutils.OPFLog; @@ -77,13 +78,18 @@ public class GCMProvider extends BasePushProvider implements SenderPushProvider private ExecutorService registrationExecutor; @NonNull - private final PreferencesProvider preferencesProvider; + private final PreferencesProvider preferencesProvider = PreferencesProvider.getInstance(getContext()); public GCMProvider(@NonNull final Context context, @NonNull final String senderID) { super(context, PROVIDER_NAME, GOOGLE_PLAY_APP_PACKAGE); + this.senderID = senderID; + } + public GCMProvider(@NonNull final Context context, + @NonNull final NotificationMaker notificationMaker, + @NonNull final String senderID) { + super(context, PROVIDER_NAME, GOOGLE_PLAY_APP_PACKAGE, notificationMaker); this.senderID = senderID; - preferencesProvider = PreferencesProvider.getInstance(context); } @Override diff --git a/opfpush-providers/nokia/src/main/java/org/onepf/opfpush/nokia/NokiaNotificationsProvider.java b/opfpush-providers/nokia/src/main/java/org/onepf/opfpush/nokia/NokiaNotificationsProvider.java index 7a0fb0a8..7bd23182 100644 --- a/opfpush-providers/nokia/src/main/java/org/onepf/opfpush/nokia/NokiaNotificationsProvider.java +++ b/opfpush-providers/nokia/src/main/java/org/onepf/opfpush/nokia/NokiaNotificationsProvider.java @@ -23,6 +23,7 @@ import org.onepf.opfpush.listener.CheckManifestHandler; import org.onepf.opfpush.model.AvailabilityResult; +import org.onepf.opfpush.notification.NotificationMaker; import org.onepf.opfutils.OPFLog; import static org.onepf.opfpush.nokia.NokiaPushConstants.NOKIA_MANUFACTURER; @@ -51,6 +52,18 @@ public NokiaNotificationsProvider(@NonNull final Context context, } } + public NokiaNotificationsProvider(@NonNull final Context context, + @NonNull final NotificationMaker notificationMaker, + @NonNull final String... sendersIds) { + if (Build.MANUFACTURER.equals(NOKIA_MANUFACTURER)) { + OPFLog.d("It's a Nokia device."); + provider = new NokiaNotificationsProviderImpl(context, notificationMaker, sendersIds); + } else { + OPFLog.d("It's no a Nokia device."); + provider = new NokiaNotificationsProviderStub(); + } + } + @Override public void register() { provider.register(); @@ -90,6 +103,12 @@ public String getHostAppPackage() { return provider.getHostAppPackage(); } + @NonNull + @Override + public NotificationMaker getNotificationMaker() { + return provider.getNotificationMaker(); + } + @Override public void checkManifest(@Nullable final CheckManifestHandler checkManifestHandler) { provider.checkManifest(checkManifestHandler); diff --git a/opfpush-providers/nokia/src/main/java/org/onepf/opfpush/nokia/NokiaNotificationsProviderImpl.java b/opfpush-providers/nokia/src/main/java/org/onepf/opfpush/nokia/NokiaNotificationsProviderImpl.java index 92e2aa38..45da5730 100644 --- a/opfpush-providers/nokia/src/main/java/org/onepf/opfpush/nokia/NokiaNotificationsProviderImpl.java +++ b/opfpush-providers/nokia/src/main/java/org/onepf/opfpush/nokia/NokiaNotificationsProviderImpl.java @@ -27,6 +27,7 @@ import org.onepf.opfpush.BasePushProvider; import org.onepf.opfpush.listener.CheckManifestHandler; import org.onepf.opfpush.model.AvailabilityResult; +import org.onepf.opfpush.notification.NotificationMaker; import org.onepf.opfpush.utils.CheckUtils; import org.onepf.opfutils.OPFLog; @@ -55,6 +56,13 @@ public NokiaNotificationsProviderImpl(@NonNull final Context context, this.sendersIds = sendersIds; } + public NokiaNotificationsProviderImpl(@NonNull final Context context, + @NonNull final NotificationMaker notificationMaker, + @NonNull final String... sendersIds) { + super(context, PROVIDER_NAME, NOKIA_STORE_APP_PACKAGE, notificationMaker); + this.sendersIds = sendersIds; + } + @NonNull @Override public AvailabilityResult getAvailabilityResult() { diff --git a/opfpush-providers/nokia/src/main/java/org/onepf/opfpush/nokia/NokiaNotificationsProviderStub.java b/opfpush-providers/nokia/src/main/java/org/onepf/opfpush/nokia/NokiaNotificationsProviderStub.java index 7182e59a..b94e4a3b 100644 --- a/opfpush-providers/nokia/src/main/java/org/onepf/opfpush/nokia/NokiaNotificationsProviderStub.java +++ b/opfpush-providers/nokia/src/main/java/org/onepf/opfpush/nokia/NokiaNotificationsProviderStub.java @@ -17,11 +17,13 @@ package org.onepf.opfpush.nokia; import android.content.Context; +import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import org.onepf.opfpush.listener.CheckManifestHandler; import org.onepf.opfpush.model.AvailabilityResult; +import org.onepf.opfpush.notification.NotificationMaker; import org.onepf.opfutils.OPFLog; import static org.onepf.opfpush.nokia.NokiaPushConstants.PROVIDER_NAME; @@ -100,6 +102,23 @@ public String getHostAppPackage() { return null; } + @NonNull + @Override + public NotificationMaker getNotificationMaker() { + OPFLog.logMethod(); + return new NotificationMaker() { + @Override + public boolean needShowNotification(@NonNull Bundle bundle) { + return false; + } + + @Override + public void showNotification(@NonNull Context context, @NonNull Bundle bundle) { + //nothing + } + }; + } + @Override public void checkManifest(@Nullable final CheckManifestHandler checkManifestHandler) { OPFLog.logMethod(); diff --git a/opfpush/src/main/java/org/onepf/opfpush/BasePushProvider.java b/opfpush/src/main/java/org/onepf/opfpush/BasePushProvider.java index c05d3ece..3af4e80f 100644 --- a/opfpush/src/main/java/org/onepf/opfpush/BasePushProvider.java +++ b/opfpush/src/main/java/org/onepf/opfpush/BasePushProvider.java @@ -23,6 +23,8 @@ import org.onepf.opfpush.listener.CheckManifestHandler; import org.onepf.opfpush.model.AvailabilityResult; +import org.onepf.opfpush.notification.NotificationMaker; +import org.onepf.opfpush.notification.OPFNotificationMaker; import org.onepf.opfpush.pushprovider.PushProvider; import org.onepf.opfpush.utils.CheckUtils; import org.onepf.opfutils.OPFUtils; @@ -51,6 +53,9 @@ public abstract class BasePushProvider implements PushProvider { @NonNull private final String hostAppPackage; + @NonNull + private final NotificationMaker notificationMaker; + /** * Creates a push provider. * @@ -62,9 +67,18 @@ public abstract class BasePushProvider implements PushProvider { protected BasePushProvider(@NonNull final Context context, @NonNull final String name, @NonNull final String hostAppPackage) { + this(context, name, hostAppPackage, new OPFNotificationMaker()); + } + + //TODO javadoc + protected BasePushProvider(@NonNull final Context context, + @NonNull final String name, + @NonNull final String hostAppPackage, + @NonNull final NotificationMaker notificationMaker) { this.appContext = context.getApplicationContext(); this.name = name; this.hostAppPackage = hostAppPackage; + this.notificationMaker = notificationMaker; } @NonNull @@ -116,6 +130,12 @@ public String getHostAppPackage() { return hostAppPackage; } + @NonNull + @Override + public NotificationMaker getNotificationMaker() { + return notificationMaker; + } + @Override public String toString() { return name + "(hostAppPackage='" + hostAppPackage + ')'; diff --git a/opfpush/src/main/java/org/onepf/opfpush/OPFPushHelperImpl.java b/opfpush/src/main/java/org/onepf/opfpush/OPFPushHelperImpl.java index 920c79b9..655c4745 100644 --- a/opfpush/src/main/java/org/onepf/opfpush/OPFPushHelperImpl.java +++ b/opfpush/src/main/java/org/onepf/opfpush/OPFPushHelperImpl.java @@ -32,6 +32,7 @@ import org.onepf.opfpush.model.PushError; import org.onepf.opfpush.model.State; import org.onepf.opfpush.model.UnrecoverablePushError; +import org.onepf.opfpush.notification.NotificationMaker; import org.onepf.opfpush.pushprovider.PushProvider; import org.onepf.opfutils.OPFChecks; import org.onepf.opfutils.OPFLog; @@ -697,7 +698,13 @@ public void onMessage(@NonNull final String providerName, OPFLog.logMethod(providerName); if (currentProvider != null && providerName.equals(currentProvider.getName())) { settings.saveState(REGISTERED); - eventListenerWrapper.onMessage(appContext, providerName, extras); + + final NotificationMaker notificationMaker = currentProvider.getNotificationMaker(); + if (extras != null && notificationMaker.needShowNotification(extras)) { + notificationMaker.showNotification(appContext, extras); + } else { + eventListenerWrapper.onMessage(appContext, providerName, extras); + } } else { OPFLog.w("Ignore onMessage from provider " + providerName + ". Current provider is " + currentProvider); diff --git a/opfpush/src/main/java/org/onepf/opfpush/model/NotificationPayload.java b/opfpush/src/main/java/org/onepf/opfpush/model/NotificationPayload.java new file mode 100644 index 00000000..1254ad56 --- /dev/null +++ b/opfpush/src/main/java/org/onepf/opfpush/model/NotificationPayload.java @@ -0,0 +1,188 @@ +/* + * Copyright 2012-2015 One Platform Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onepf.opfpush.model; + +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.text.TextUtils; + +/** + * TODO: javadoc + * + * @author Roman Savin + * @since 23.06.2015 + */ +@SuppressWarnings("PMD.MissingStaticMethodInNonInstantiatableClass") +public final class NotificationPayload { + + @NonNull + private final String title; + + @NonNull + private final String icon; + + @Nullable + private final String body; + + @Nullable + private final String sound; + + @Nullable + private final String tag; + + @Nullable + private final String color; + + @Nullable + private final String clickAction; + + private NotificationPayload(@NonNull final String title, + @NonNull final String icon, + @Nullable final String body, + @Nullable final String sound, + @Nullable final String tag, + @Nullable final String color, + @Nullable final String clickAction) { + this.title = title; + this.icon = icon; + this.body = body; + this.sound = sound; + this.tag = tag; + this.color = color; + this.clickAction = clickAction; + } + + @NonNull + public String getTitle() { + return title; + } + + @NonNull + public String getIcon() { + return icon; + } + + @Nullable + public String getBody() { + return body; + } + + @Nullable + public String getSound() { + return sound; + } + + @Nullable + public String getTag() { + return tag; + } + + @Nullable + public String getColor() { + return color; + } + + @Nullable + public String getClickAction() { + return clickAction; + } + + @Override + public String toString() { + return "NotificationPayload : {" + + " title : " + title + + ", icon : " + icon + + ", body : " + body + + ", sound : " + sound + + ", tag : " + tag + + ", color : " + color + + ", clickAction : " + clickAction + + "}"; + } + + public static final class Builder { + + @Nullable + private String title; + + @Nullable + private String icon; + + @Nullable + private String body; + + @Nullable + private String sound; + + @Nullable + private String tag; + + @Nullable + private String color; + + @Nullable + private String clickAction; + + public Builder setTitle(@NonNull final String title) { + this.title = title; + return this; + } + + public Builder setIcon(@NonNull final String icon) { + this.icon = icon; + return this; + } + + public Builder setBody(@Nullable final String body) { + this.body = body; + return this; + } + + public Builder setSound(@Nullable final String sound) { + this.sound = sound; + return this; + } + + public Builder setTag(@Nullable final String tag) { + this.tag = tag; + return this; + } + + public Builder setColor(@Nullable final String color) { + this.color = color; + return this; + } + + public Builder setClickAction(@Nullable final String clickAction) { + this.clickAction = clickAction; + return this; + } + + @SuppressWarnings("PMD.AccessorClassGeneration") + public NotificationPayload build() { + if (TextUtils.isEmpty(title)) { + throw new IllegalArgumentException("Title can't be empty"); + } + + if (TextUtils.isEmpty(icon)) { + throw new IllegalArgumentException("Icon can't be empty"); + } + + return new NotificationPayload(title, icon, body, sound, tag, color, clickAction); + } + } +} diff --git a/opfpush/src/main/java/org/onepf/opfpush/notification/NotificationMaker.java b/opfpush/src/main/java/org/onepf/opfpush/notification/NotificationMaker.java new file mode 100644 index 00000000..bb1e4867 --- /dev/null +++ b/opfpush/src/main/java/org/onepf/opfpush/notification/NotificationMaker.java @@ -0,0 +1,34 @@ +/* + * Copyright 2012-2015 One Platform Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onepf.opfpush.notification; + +import android.content.Context; +import android.os.Bundle; +import android.support.annotation.NonNull; + +/** + * TODO: javadoc + * + * @author Roman Savin + * @since 23.06.2015 + */ +public interface NotificationMaker { + + boolean needShowNotification(@NonNull final Bundle bundle); + + void showNotification(@NonNull final Context context, @NonNull final Bundle bundle); +} diff --git a/opfpush/src/main/java/org/onepf/opfpush/notification/NotificationPreparer.java b/opfpush/src/main/java/org/onepf/opfpush/notification/NotificationPreparer.java new file mode 100644 index 00000000..ba97b5d9 --- /dev/null +++ b/opfpush/src/main/java/org/onepf/opfpush/notification/NotificationPreparer.java @@ -0,0 +1,34 @@ +/* + * Copyright 2012-2015 One Platform Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onepf.opfpush.notification; + +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import org.onepf.opfpush.model.NotificationPayload; + +/** + * TODO: javadoc + * + * @author Roman Savin + * @since 23.06.2015 + */ +public interface NotificationPreparer { + + @Nullable + NotificationPayload prepare(@NonNull final Bundle bundle); +} diff --git a/opfpush/src/main/java/org/onepf/opfpush/notification/OPFNotificationMaker.java b/opfpush/src/main/java/org/onepf/opfpush/notification/OPFNotificationMaker.java new file mode 100644 index 00000000..55ed57cb --- /dev/null +++ b/opfpush/src/main/java/org/onepf/opfpush/notification/OPFNotificationMaker.java @@ -0,0 +1,58 @@ +/* + * Copyright 2012-2015 One Platform Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onepf.opfpush.notification; + +import android.content.Context; +import android.os.Bundle; +import android.support.annotation.NonNull; +import org.onepf.opfpush.utils.NotificationUtils; +import org.onepf.opfutils.OPFLog; +import org.onepf.opfutils.OPFUtils; + +/** + * TODO: add javadoc + * + * @author Roman Savin + * @since 23.06.2015 + */ +public final class OPFNotificationMaker implements NotificationMaker { + + private static final String SHOW_NOTIFICATION_KEY = "show_opf_notification"; + + @NonNull + private NotificationPreparer notificationPreparer; + + public OPFNotificationMaker() { + this(new OPFNotificationPreparer()); + } + + public OPFNotificationMaker(@NonNull final NotificationPreparer notificationPreparer) { + this.notificationPreparer = notificationPreparer; + } + + @Override + public boolean needShowNotification(@NonNull final Bundle bundle) { + OPFLog.logMethod(OPFUtils.toString(bundle)); + return bundle.getBoolean(SHOW_NOTIFICATION_KEY); + } + + @Override + public void showNotification(@NonNull final Context context, @NonNull final Bundle bundle) { + OPFLog.logMethod(context, OPFUtils.toString(bundle)); + NotificationUtils.showNotification(context, bundle, notificationPreparer); + } +} diff --git a/opfpush/src/main/java/org/onepf/opfpush/notification/OPFNotificationPreparer.java b/opfpush/src/main/java/org/onepf/opfpush/notification/OPFNotificationPreparer.java new file mode 100644 index 00000000..6c00ac61 --- /dev/null +++ b/opfpush/src/main/java/org/onepf/opfpush/notification/OPFNotificationPreparer.java @@ -0,0 +1,71 @@ +/* + * Copyright 2012-2015 One Platform Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onepf.opfpush.notification; + +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.text.TextUtils; +import org.onepf.opfpush.model.NotificationPayload; +import org.onepf.opfutils.OPFLog; +import org.onepf.opfutils.OPFUtils; + +/** + * TODO: javadoc + * + * @author Roman Savin + * @since 23.06.2015 + */ +public final class OPFNotificationPreparer implements NotificationPreparer { + + private static final String TITLE = "title"; + private static final String ICON = "icon"; + private static final String BODY = "body"; + private static final String SOUND = "sound"; + private static final String TAG = "tag"; + private static final String COLOR = "color"; + private static final String CLICK_ACTION = "click_action"; + + @Nullable + @Override + public NotificationPayload prepare(@NonNull final Bundle bundle) { + OPFLog.logMethod(OPFUtils.toString(bundle)); + final String title = bundle.getString(TITLE); + if (TextUtils.isEmpty(title)) { + OPFLog.i("Notification title is empty. Notification will not be shown"); + return null; + } + + final String icon = bundle.getString(ICON); + if (TextUtils.isEmpty(icon)) { + OPFLog.i("Notification icon is empty. Notification will not be shown"); + return null; + } + + final NotificationPayload.Builder builder = new NotificationPayload.Builder() + .setTitle(title) + .setIcon(icon) + .setBody(bundle.getString(BODY)) + .setSound(bundle.getString(SOUND)) + .setTag(bundle.getString(TAG)) + .setColor(bundle.getString(COLOR)) + .setClickAction(bundle.getString(CLICK_ACTION)); + + + return builder.build(); + } +} diff --git a/opfpush/src/main/java/org/onepf/opfpush/pushprovider/PushProvider.java b/opfpush/src/main/java/org/onepf/opfpush/pushprovider/PushProvider.java index 65537275..ef4a7877 100644 --- a/opfpush/src/main/java/org/onepf/opfpush/pushprovider/PushProvider.java +++ b/opfpush/src/main/java/org/onepf/opfpush/pushprovider/PushProvider.java @@ -21,6 +21,7 @@ import org.onepf.opfpush.listener.CheckManifestHandler; import org.onepf.opfpush.model.AvailabilityResult; +import org.onepf.opfpush.notification.NotificationMaker; /** * The {@code PushProvider} interface represent the provider for push notification from the server to @@ -92,6 +93,10 @@ public interface PushProvider { @Nullable String getHostAppPackage(); + //TODO javadoc + @NonNull + NotificationMaker getNotificationMaker(); + /** * Verify that application manifest contains all needed permissions. * diff --git a/opfpush/src/main/java/org/onepf/opfpush/utils/NotificationUtils.java b/opfpush/src/main/java/org/onepf/opfpush/utils/NotificationUtils.java new file mode 100644 index 00000000..905aa509 --- /dev/null +++ b/opfpush/src/main/java/org/onepf/opfpush/utils/NotificationUtils.java @@ -0,0 +1,153 @@ +/* + * Copyright 2012-2015 One Platform Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onepf.opfpush.utils; + +import android.annotation.SuppressLint; +import android.app.Notification; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.graphics.Color; +import android.os.Build.VERSION; +import android.os.Build.VERSION_CODES; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.text.TextUtils; +import org.onepf.opfpush.model.NotificationPayload; +import org.onepf.opfpush.notification.NotificationPreparer; +import org.onepf.opfpush.notification.OPFNotificationPreparer; +import org.onepf.opfutils.OPFLog; +import org.onepf.opfutils.OPFUtils; + +import java.util.regex.Pattern; + +import static android.app.Notification.DEFAULT_SOUND; +import static android.content.Context.NOTIFICATION_SERVICE; +import static java.util.Locale.US; + +/** + * TODO: javadoc + * + * @author Roman Savin + * @since 23.06.2015 + */ +public final class NotificationUtils { + + private static final String HEX_COLOR_PATTERN = "^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$"; + private static final Pattern COLOR_PATTERN = Pattern.compile(HEX_COLOR_PATTERN); + + private static final String SOUND_DEFAULT_VALUE = "default"; + + private static final String DEFAULT_TAG_PREFIX = "OPF-Notification:"; + + private NotificationUtils() { + throw new UnsupportedOperationException(); + } + + public static void showNotification(@NonNull final Context context, + @NonNull final Bundle bundle) { + showNotification(context, bundle, new OPFNotificationPreparer()); + } + + public static void showNotification(@NonNull final Context context, + @NonNull final Bundle bundle, + @NonNull final NotificationPreparer notificationPreparer) { + OPFLog.logMethod(context, OPFUtils.toString(bundle), notificationPreparer); + final NotificationPayload notificationPayload = notificationPreparer.prepare(bundle); + if (notificationPayload == null) { + return; + } + + final String icon = notificationPayload.getIcon(); + final int iconDrawableId = context.getResources().getIdentifier(icon, "drawable", context.getPackageName()); + + if (iconDrawableId == 0) { + OPFLog.i(String.format(US, "Can't find drawable with name : \"%s\". Notification will not be shown", icon)); + return; + } + + final Notification.Builder notificationBuilder = new Notification.Builder(context) + .setContentTitle(notificationPayload.getTitle()) + .setSmallIcon(iconDrawableId) + .setContentText(notificationPayload.getBody()); + + final String sound = notificationPayload.getSound(); + if (!TextUtils.isEmpty(sound)) { + safeSetSound(notificationBuilder, sound); + } + + final String color = notificationPayload.getColor(); + if (!TextUtils.isEmpty(color)) { + safeSetColor(notificationBuilder, color); + } + + final String clickAction = notificationPayload.getClickAction(); + if (!TextUtils.isEmpty(clickAction)) { + setContentIntent(notificationBuilder, context, clickAction, bundle); + } + + final String tag = TextUtils.isEmpty(notificationPayload.getTag()) + ? DEFAULT_TAG_PREFIX + System.currentTimeMillis() + : notificationPayload.getTag(); + final NotificationManager notificationManager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE); + notificationManager.notify(tag, 0, buildNotification(notificationBuilder)); + } + + private static void safeSetSound(@NonNull final Notification.Builder notificationBuilder, + @NonNull final String sound) { + if (SOUND_DEFAULT_VALUE.equals(sound)) { + notificationBuilder.setDefaults(DEFAULT_SOUND); + } else { + OPFLog.i(String.format(US, "Sound \"%s\" is not supported. Only \"default\" sound is supported currently.", sound)); + } + } + + @SuppressLint("NewApi") + private static void safeSetColor(@NonNull final Notification.Builder notificationBuilder, + @NonNull final String color) { + //todo: check on not lolipop devices + if (!COLOR_PATTERN.matcher(color).matches()) { + OPFLog.i(String.format(US, "Color \"%s\" doesn't match to #rrggbb format.", color)); + } else if (!isSetColorSupported()) { + OPFLog.i("Notification.Builder.setColor() is not supported"); + } else { + notificationBuilder.setColor(Color.parseColor(color)); + } + } + + private static void setContentIntent(@NonNull final Notification.Builder notificationBuilder, + @NonNull final Context context, + @NonNull final String clickAction, + @NonNull final Bundle bundle) { + final Intent intent = new Intent(clickAction); + intent.setPackage(context.getPackageName()); + intent.putExtras(bundle); + + notificationBuilder.setContentIntent(PendingIntent.getActivity(context, 0, intent, 0)); + } + + private static boolean isSetColorSupported() { + return VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP; + } + + @SuppressWarnings("deprecation") + @SuppressLint("NewApi") + private static Notification buildNotification(@NonNull final Notification.Builder builder) { + return VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN ? builder.build() : builder.getNotification(); + } +} diff --git a/opfpush/src/test/java/org/onepf/opfpush/mock/MockPushProvider.java b/opfpush/src/test/java/org/onepf/opfpush/mock/MockPushProvider.java index 29744156..d0aa9afd 100644 --- a/opfpush/src/test/java/org/onepf/opfpush/mock/MockPushProvider.java +++ b/opfpush/src/test/java/org/onepf/opfpush/mock/MockPushProvider.java @@ -7,6 +7,8 @@ import org.onepf.opfpush.listener.CheckManifestHandler; import org.onepf.opfpush.model.AvailabilityResult; import org.onepf.opfpush.model.PushError; +import org.onepf.opfpush.notification.NotificationMaker; +import org.onepf.opfpush.notification.OPFNotificationMaker; import org.onepf.opfpush.pushprovider.PushProvider; import org.onepf.opfpush.testutil.Util; @@ -101,6 +103,12 @@ public String getHostAppPackage() { return hostAppPackage; } + @NonNull + @Override + public NotificationMaker getNotificationMaker() { + return new OPFNotificationMaker(); + } + @Override public void checkManifest(@Nullable CheckManifestHandler checkManifestHandler) { // nothing From 6e586ff2767a37c77e220a6791d619dc8ef13f85 Mon Sep 17 00:00:00 2001 From: Roman Savin Date: Wed, 24 Jun 2015 16:44:23 +0300 Subject: [PATCH 08/29] Change dependencies of modules to compile project. --- opfpush-providers/adm/build.gradle | 4 +--- opfpush-providers/gcm/build.gradle | 4 +--- opfpush-providers/nokia/build.gradle | 4 +--- samples/pushchat/build.gradle | 16 ++++------------ 4 files changed, 7 insertions(+), 21 deletions(-) diff --git a/opfpush-providers/adm/build.gradle b/opfpush-providers/adm/build.gradle index a9484300..bbab2a38 100644 --- a/opfpush-providers/adm/build.gradle +++ b/opfpush-providers/adm/build.gradle @@ -31,9 +31,7 @@ dependencies { androidTestCompile 'junit:junit:4.12' androidTestCompile 'org.robolectric:robolectric:2.4' - compile ('org.onepf:opfpush:0.2.+@aar') { - changing = true - } + compile project(':opfpush') provided 'com.amazon:amazon-device-messaging:1.0.1' provided 'com.android.support:support-annotations:19.1.0' diff --git a/opfpush-providers/gcm/build.gradle b/opfpush-providers/gcm/build.gradle index e333379c..f7c1f2f4 100644 --- a/opfpush-providers/gcm/build.gradle +++ b/opfpush-providers/gcm/build.gradle @@ -31,9 +31,7 @@ dependencies { androidTestCompile 'junit:junit:4.12' androidTestCompile 'org.robolectric:robolectric:2.4' - compile ('org.onepf:opfpush:0.2.+@aar') { - changing = true - } + compile project(':opfpush') //noinspection NewerVersionAvailable compile 'com.google.android.gms:play-services-gcm:7.5.0' diff --git a/opfpush-providers/nokia/build.gradle b/opfpush-providers/nokia/build.gradle index 51c7bc69..5fe5b3fa 100644 --- a/opfpush-providers/nokia/build.gradle +++ b/opfpush-providers/nokia/build.gradle @@ -26,9 +26,7 @@ android { } dependencies { - compile ('org.onepf:opfpush:0.2.+@aar') { - changing = true - } + compile project(':opfpush') compile 'com.nokia:push:1.0' provided 'com.android.support:support-annotations:19.1.0' diff --git a/samples/pushchat/build.gradle b/samples/pushchat/build.gradle index 40d714e5..3e1fbc18 100644 --- a/samples/pushchat/build.gradle +++ b/samples/pushchat/build.gradle @@ -52,18 +52,10 @@ dependencies { //opfpush compile 'org.onepf:opfutils:0.1.22' - compile('org.onepf:opfpush:0.2.+@aar') { - changing = true - } - compile('org.onepf:opfpush-adm:0.2.+@aar') { - changing = true - } - compile('org.onepf:opfpush-gcm:0.2.+@aar') { - changing = true - } - compile('org.onepf:opfpush-nokia:0.2.+@aar') { - changing = true - } + compile project(':opfpush') + compile project(':adm') + compile project(':gcm') + compile project(':nokia') //push providers dependencies provided 'com.amazon:amazon-device-messaging:1.0.1' From 7b98847f82c86273d9b0ef685414af010586d4ac Mon Sep 17 00:00:00 2001 From: Roman Savin Date: Wed, 24 Jun 2015 16:44:49 +0300 Subject: [PATCH 09/29] Change SHOW_NOTIFICATION_KEY to "opf_notification". --- .../org/onepf/opfpush/notification/OPFNotificationMaker.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/opfpush/src/main/java/org/onepf/opfpush/notification/OPFNotificationMaker.java b/opfpush/src/main/java/org/onepf/opfpush/notification/OPFNotificationMaker.java index 55ed57cb..1ed6bc2a 100644 --- a/opfpush/src/main/java/org/onepf/opfpush/notification/OPFNotificationMaker.java +++ b/opfpush/src/main/java/org/onepf/opfpush/notification/OPFNotificationMaker.java @@ -31,7 +31,7 @@ */ public final class OPFNotificationMaker implements NotificationMaker { - private static final String SHOW_NOTIFICATION_KEY = "show_opf_notification"; + private static final String SHOW_NOTIFICATION_KEY = "opf_notification"; @NonNull private NotificationPreparer notificationPreparer; @@ -47,7 +47,7 @@ public OPFNotificationMaker(@NonNull final NotificationPreparer notificationPrep @Override public boolean needShowNotification(@NonNull final Bundle bundle) { OPFLog.logMethod(OPFUtils.toString(bundle)); - return bundle.getBoolean(SHOW_NOTIFICATION_KEY); + return Boolean.parseBoolean(bundle.getString(SHOW_NOTIFICATION_KEY)); } @Override From 89bf44a964a8f423895d8dc068cc529c453818e9 Mon Sep 17 00:00:00 2001 From: Roman Savin Date: Wed, 24 Jun 2015 18:11:30 +0300 Subject: [PATCH 10/29] Wrap working with NotificationMaker into main thread handler. --- .../org/onepf/opfpush/OPFPushHelperImpl.java | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/opfpush/src/main/java/org/onepf/opfpush/OPFPushHelperImpl.java b/opfpush/src/main/java/org/onepf/opfpush/OPFPushHelperImpl.java index 655c4745..354c6346 100644 --- a/opfpush/src/main/java/org/onepf/opfpush/OPFPushHelperImpl.java +++ b/opfpush/src/main/java/org/onepf/opfpush/OPFPushHelperImpl.java @@ -19,6 +19,8 @@ import android.content.Context; import android.content.Intent; import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.text.TextUtils; @@ -686,6 +688,7 @@ private boolean isOPFReceiverRegistered() { @SuppressWarnings("UnusedDeclaration") private final class ReceivedMessageHandlerImpl implements ReceivedMessageHandler { + private final Handler handler = new Handler(Looper.getMainLooper()); /** * A push provider calls this method when a new message is received. * @@ -699,12 +702,20 @@ public void onMessage(@NonNull final String providerName, if (currentProvider != null && providerName.equals(currentProvider.getName())) { settings.saveState(REGISTERED); - final NotificationMaker notificationMaker = currentProvider.getNotificationMaker(); - if (extras != null && notificationMaker.needShowNotification(extras)) { - notificationMaker.showNotification(appContext, extras); - } else { - eventListenerWrapper.onMessage(appContext, providerName, extras); - } + //noinspection InnerClassTooDeeplyNested + handler.post(new Runnable() { + @Override + public void run() { + //All operations with NotificationMaker should are performed in the main thread. + //It saves users from having to make thread safe NotificationMaker. + final NotificationMaker notificationMaker = currentProvider.getNotificationMaker(); + if (extras != null && notificationMaker.needShowNotification(extras)) { + notificationMaker.showNotification(appContext, extras); + } else { + eventListenerWrapper.onMessage(appContext, providerName, extras); + } + } + }); } else { OPFLog.w("Ignore onMessage from provider " + providerName + ". Current provider is " + currentProvider); From d169d35c6d1fc3f4316ea622bcc4127f13a23145 Mon Sep 17 00:00:00 2001 From: Roman Savin Date: Wed, 24 Jun 2015 20:06:27 +0300 Subject: [PATCH 11/29] Perform a few fixes. --- .../main/java/org/onepf/opfpush/utils/NotificationUtils.java | 4 ++-- samples/pushchat/src/main/AndroidManifest.xml | 1 + .../src/main/java/org/onepf/pushchat/PushChatApplication.java | 1 - 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/opfpush/src/main/java/org/onepf/opfpush/utils/NotificationUtils.java b/opfpush/src/main/java/org/onepf/opfpush/utils/NotificationUtils.java index 905aa509..2e2fa61e 100644 --- a/opfpush/src/main/java/org/onepf/opfpush/utils/NotificationUtils.java +++ b/opfpush/src/main/java/org/onepf/opfpush/utils/NotificationUtils.java @@ -84,7 +84,8 @@ public static void showNotification(@NonNull final Context context, final Notification.Builder notificationBuilder = new Notification.Builder(context) .setContentTitle(notificationPayload.getTitle()) .setSmallIcon(iconDrawableId) - .setContentText(notificationPayload.getBody()); + .setContentText(notificationPayload.getBody()) + .setAutoCancel(true); final String sound = notificationPayload.getSound(); if (!TextUtils.isEmpty(sound)) { @@ -120,7 +121,6 @@ private static void safeSetSound(@NonNull final Notification.Builder notificatio @SuppressLint("NewApi") private static void safeSetColor(@NonNull final Notification.Builder notificationBuilder, @NonNull final String color) { - //todo: check on not lolipop devices if (!COLOR_PATTERN.matcher(color).matches()) { OPFLog.i(String.format(US, "Color \"%s\" doesn't match to #rrggbb format.", color)); } else if (!isSetColorSupported()) { diff --git a/samples/pushchat/src/main/AndroidManifest.xml b/samples/pushchat/src/main/AndroidManifest.xml index 9f391de7..cda13f09 100644 --- a/samples/pushchat/src/main/AndroidManifest.xml +++ b/samples/pushchat/src/main/AndroidManifest.xml @@ -37,6 +37,7 @@ + diff --git a/samples/pushchat/src/main/java/org/onepf/pushchat/PushChatApplication.java b/samples/pushchat/src/main/java/org/onepf/pushchat/PushChatApplication.java index fd3de800..b4153185 100644 --- a/samples/pushchat/src/main/java/org/onepf/pushchat/PushChatApplication.java +++ b/samples/pushchat/src/main/java/org/onepf/pushchat/PushChatApplication.java @@ -17,7 +17,6 @@ package org.onepf.pushchat; import android.app.Application; - import com.squareup.leakcanary.LeakCanary; import com.squareup.leakcanary.RefWatcher; import org.onepf.opfpush.OPFPush; From 0d322d88dcd038e133be87ba2c616258c38aa947 Mon Sep 17 00:00:00 2001 From: Roman Savin Date: Thu, 25 Jun 2015 19:42:22 +0300 Subject: [PATCH 12/29] Implement onTokenRefresh() method for GCM provider. --- .../gcm/GCMInstanceIDListenerService.java | 11 +++++++- .../onepf/opfpush/BootCompleteReceiver.java | 2 +- .../java/org/onepf/opfpush/OPFPushHelper.java | 7 ++++-- .../org/onepf/opfpush/OPFPushHelperImpl.java | 25 ++++++++++--------- .../org/onepf/opfpush/OPFPushHelperStub.java | 10 ++++---- .../onepf/opfpush/PackageChangeReceiver.java | 2 +- samples/pushchat/src/main/AndroidManifest.xml | 1 + 7 files changed, 36 insertions(+), 22 deletions(-) diff --git a/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMInstanceIDListenerService.java b/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMInstanceIDListenerService.java index 83b5378a..86d661dc 100644 --- a/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMInstanceIDListenerService.java +++ b/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMInstanceIDListenerService.java @@ -17,11 +17,20 @@ package org.onepf.opfpush.gcm; import com.google.android.gms.iid.InstanceIDListenerService; +import org.onepf.opfpush.OPFPush; +import org.onepf.opfutils.OPFLog; /** + * TODO javadoc + * * @author Roman Savin * @since 16.06.2015 */ public class GCMInstanceIDListenerService extends InstanceIDListenerService { - //todo implement + + @Override + public void onTokenRefresh() { + OPFLog.logMethod(); + OPFPush.getHelper().onNeedRetryRegistration(); + } } diff --git a/opfpush/src/main/java/org/onepf/opfpush/BootCompleteReceiver.java b/opfpush/src/main/java/org/onepf/opfpush/BootCompleteReceiver.java index e3f0de5d..514db879 100644 --- a/opfpush/src/main/java/org/onepf/opfpush/BootCompleteReceiver.java +++ b/opfpush/src/main/java/org/onepf/opfpush/BootCompleteReceiver.java @@ -42,7 +42,7 @@ public void onReceive(@NonNull final Context context, @NonNull final Intent inte OPFLog.i("Helper is registered"); if (isAndroidIDChanged(context)) { OPFLog.i("Android ID changed."); - helper.onNeedRetryRegister(); + helper.onNeedRetryRegistration(); } else { OPFLog.i("Android ID hasn't been changed"); } diff --git a/opfpush/src/main/java/org/onepf/opfpush/OPFPushHelper.java b/opfpush/src/main/java/org/onepf/opfpush/OPFPushHelper.java index 46876c71..066f58c1 100644 --- a/opfpush/src/main/java/org/onepf/opfpush/OPFPushHelper.java +++ b/opfpush/src/main/java/org/onepf/opfpush/OPFPushHelper.java @@ -119,6 +119,11 @@ private void sendMessage(@NonNull final Message message) { */ public abstract boolean isRegistered(); + /** + * Is invoked if registration must be retried. (For example if registration id is expired). + */ + public abstract void onNeedRetryRegistration(); + /** * Returns {@code true} if the registration operation is being performed at the moment. * @@ -136,8 +141,6 @@ private void sendMessage(@NonNull final Message message) { abstract void unregister(@NonNull final String providerName); - abstract void onNeedRetryRegister(); - abstract void registerNextAvailableProvider(@Nullable final String prevProviderName); @Nullable diff --git a/opfpush/src/main/java/org/onepf/opfpush/OPFPushHelperImpl.java b/opfpush/src/main/java/org/onepf/opfpush/OPFPushHelperImpl.java index 354c6346..d7eedb05 100644 --- a/opfpush/src/main/java/org/onepf/opfpush/OPFPushHelperImpl.java +++ b/opfpush/src/main/java/org/onepf/opfpush/OPFPushHelperImpl.java @@ -280,6 +280,18 @@ public boolean isRegistering() { return settings.getState() == REGISTERING; } + @Override + public void onNeedRetryRegistration() { + OPFLog.logMethod(); + OPFLog.d("Current provider : " + currentProvider); + settings.clear(); + if (currentProvider != null) { + currentProvider.onRegistrationInvalid(); + currentProvider = null; + } + register(); + } + @NonNull @Override public String toString() { @@ -364,18 +376,6 @@ void unregister(@NonNull final String providerName) { } } - @Override - void onNeedRetryRegister() { - OPFLog.logMethod(); - OPFLog.d("Current provider : " + currentProvider); - settings.clear(); - if (currentProvider != null) { - currentProvider.onRegistrationInvalid(); - currentProvider = null; - } - register(); - } - @SuppressWarnings("PMD.OneDeclarationPerLine") @Override void registerNextAvailableProvider(@Nullable final String prevProviderName) { @@ -689,6 +689,7 @@ private boolean isOPFReceiverRegistered() { private final class ReceivedMessageHandlerImpl implements ReceivedMessageHandler { private final Handler handler = new Handler(Looper.getMainLooper()); + /** * A push provider calls this method when a new message is received. * diff --git a/opfpush/src/main/java/org/onepf/opfpush/OPFPushHelperStub.java b/opfpush/src/main/java/org/onepf/opfpush/OPFPushHelperStub.java index 06a31b8d..3f7e138b 100644 --- a/opfpush/src/main/java/org/onepf/opfpush/OPFPushHelperStub.java +++ b/opfpush/src/main/java/org/onepf/opfpush/OPFPushHelperStub.java @@ -82,6 +82,11 @@ public boolean isRegistering() { return false; } + @Override + public void onNeedRetryRegistration() { + OPFLog.logMethod(); + } + @Override void init(@NonNull final Configuration initialConfiguration) { OPFLog.logMethod(initialConfiguration); @@ -108,11 +113,6 @@ void unregister(@NonNull final String providerName) { OPFLog.logMethod(providerName); } - @Override - void onNeedRetryRegister() { - OPFLog.logMethod(); - } - @Override void registerNextAvailableProvider(@Nullable final String prevProviderName) { OPFLog.logMethod(prevProviderName); diff --git a/opfpush/src/main/java/org/onepf/opfpush/PackageChangeReceiver.java b/opfpush/src/main/java/org/onepf/opfpush/PackageChangeReceiver.java index 038400f0..131f9dc1 100644 --- a/opfpush/src/main/java/org/onepf/opfpush/PackageChangeReceiver.java +++ b/opfpush/src/main/java/org/onepf/opfpush/PackageChangeReceiver.java @@ -50,7 +50,7 @@ public void onReceive(@NonNull final Context context, @NonNull final Intent inte } else if (Intent.ACTION_PACKAGE_REPLACED.equals(action) && context.getPackageName().equals(getAppPackage(intent))) { OPFLog.d("Application updated."); - helper.onNeedRetryRegister(); + helper.onNeedRetryRegistration(); } } diff --git a/samples/pushchat/src/main/AndroidManifest.xml b/samples/pushchat/src/main/AndroidManifest.xml index cda13f09..a9b84e45 100644 --- a/samples/pushchat/src/main/AndroidManifest.xml +++ b/samples/pushchat/src/main/AndroidManifest.xml @@ -61,6 +61,7 @@ android:exported="true" android:permission="com.google.android.c2dm.permission.SEND"> + From 4b7ffdc996b60d864371803f84993f1d3f0feedf Mon Sep 17 00:00:00 2001 From: Roman Savin Date: Fri, 26 Jun 2015 17:52:51 +0300 Subject: [PATCH 13/29] Add GCM topics. --- .../org/onepf/opfpush/gcm/GCMConstants.java | 3 + .../org/onepf/opfpush/gcm/GCMProvider.java | 1 + .../onepf/opfpush/gcm/GCMPubSubHelper.java | 179 ++++++++++++++++++ .../ui/fragment/content/MessagesFragment.java | 1 + .../ui/fragment/content/StateFragment.java | 140 +++++++++++++- .../src/main/res/layout/fragment_state.xml | 28 +++ .../pushchat/src/main/res/values/strings.xml | 6 + 7 files changed, 356 insertions(+), 2 deletions(-) create mode 100644 opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMPubSubHelper.java diff --git a/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMConstants.java b/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMConstants.java index c0f81328..27465126 100644 --- a/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMConstants.java +++ b/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMConstants.java @@ -46,6 +46,9 @@ public final class GCMConstants { static final String GOOGLE_SERVICES_FRAMEWORK_PACKAGE = "com.google.android.gsf"; + static final String GCM_NOT_CURRENT_PROVIDER_ERROR = "GCM is no current provider"; + static final String REGISTRATION_ID_NOT_OBTAINED_ERROR = "Registration token isn't obtained"; + private GCMConstants() { throw new UnsupportedOperationException(); } diff --git a/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMProvider.java b/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMProvider.java index 161570fb..93b8f699 100644 --- a/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMProvider.java +++ b/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMProvider.java @@ -74,6 +74,7 @@ public class GCMProvider extends BasePushProvider implements SenderPushProvider private final String senderID; + //TODO: refactor executor @Nullable private ExecutorService registrationExecutor; diff --git a/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMPubSubHelper.java b/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMPubSubHelper.java new file mode 100644 index 00000000..181ef189 --- /dev/null +++ b/opfpush-providers/gcm/src/main/java/org/onepf/opfpush/gcm/GCMPubSubHelper.java @@ -0,0 +1,179 @@ +/* + * Copyright 2012-2015 One Platform Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onepf.opfpush.gcm; + +import android.content.Context; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import com.google.android.gms.gcm.GcmPubSub; +import org.onepf.opfpush.OPFPush; +import org.onepf.opfpush.OPFPushHelper; +import org.onepf.opfutils.OPFLog; + +import java.io.IOException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import static org.onepf.opfpush.gcm.GCMConstants.GCM_NOT_CURRENT_PROVIDER_ERROR; +import static org.onepf.opfpush.gcm.GCMConstants.PROVIDER_NAME; +import static org.onepf.opfpush.gcm.GCMConstants.REGISTRATION_ID_NOT_OBTAINED_ERROR; + +/** + * TODO javadoc + * + * @author Roman Savin + * @since 26.06.2015 + */ +public final class GCMPubSubHelper { + + private static volatile GCMPubSubHelper instance = null; + + @NonNull + private final GcmPubSub gcmPubSub; + + @NonNull + private final ExecutorService executorService = Executors.newSingleThreadExecutor(); + + @NonNull + private final Object pubSubMonitor = new Object(); + + private GCMPubSubHelper(@NonNull final Context context) { + this.gcmPubSub = GcmPubSub.getInstance(context); + } + + @SuppressWarnings("DoubleCheckedLocking") + public static GCMPubSubHelper getInstance(@NonNull final Context context) { + if (instance == null) { + synchronized (GCMPubSubHelper.class) { + if (instance == null) { + instance = new GCMPubSubHelper(context); + } + } + } + + return instance; + } + + public void subscribe(@NonNull final String topic, + @Nullable final Bundle extras, + @Nullable final Callback callback) { + final OPFPushHelper helper = OPFPush.getHelper(); + final Callback callbackWrapper = new CallbackMainThreadWrapper(callback); + + if (checkPubSubAvailability(helper, callbackWrapper)) { + synchronized (pubSubMonitor) { + executorService.submit(new Runnable() { + @Override + public void run() { + try { + //noinspection ConstantConditions + gcmPubSub.subscribe(helper.getRegistrationId(), topic, extras); + callbackWrapper.onSuccess(); + } catch (final IOException e) { + OPFLog.w(e.getMessage()); + callbackWrapper.onError(e.getMessage()); + } + } + }); + } + } + } + + public void unsubscribe(@NonNull final String topic, + @Nullable final Callback callback) { + final OPFPushHelper helper = OPFPush.getHelper(); + final Callback callbackWrapper = new CallbackMainThreadWrapper(callback); + + if (checkPubSubAvailability(helper, callbackWrapper)) { + synchronized (pubSubMonitor) { + executorService.submit(new Runnable() { + @Override + public void run() { + try { + //noinspection ConstantConditions + gcmPubSub.unsubscribe(helper.getRegistrationId(), topic); + callbackWrapper.onSuccess(); + } catch (final IOException e) { + OPFLog.w(e.getMessage()); + callbackWrapper.onError(e.getMessage()); + } + } + }); + } + } + } + + private boolean checkPubSubAvailability(@NonNull final OPFPushHelper helper, @NonNull final Callback callback) { + if (!PROVIDER_NAME.equals(helper.getProviderName())) { + callback.onError(GCM_NOT_CURRENT_PROVIDER_ERROR); + return false; + } else if (helper.getRegistrationId() == null) { + callback.onError(REGISTRATION_ID_NOT_OBTAINED_ERROR); + return false; + } + return true; + } + + public class CallbackMainThreadWrapper implements Callback { + + @NonNull + private final Handler handler = new Handler(Looper.getMainLooper()); + + @Nullable + private final Callback callback; + + public CallbackMainThreadWrapper(@Nullable final Callback callback) { + this.callback = callback; + } + + @SuppressWarnings("InnerClassTooDeeplyNested") + @Override + public void onSuccess() { + if (callback != null) { + handler.post(new Runnable() { + @Override + public void run() { + callback.onSuccess(); + } + }); + } + } + + @SuppressWarnings("InnerClassTooDeeplyNested") + @Override + public void onError(@Nullable final String error) { + if (callback != null) { + handler.post(new Runnable() { + @Override + public void run() { + callback.onError(error); + } + }); + } + } + } + + public interface Callback { + + void onSuccess(); + + void onError(@Nullable final String error); + } +} diff --git a/samples/pushchat/src/main/java/org/onepf/pushchat/ui/fragment/content/MessagesFragment.java b/samples/pushchat/src/main/java/org/onepf/pushchat/ui/fragment/content/MessagesFragment.java index 93e2d282..89e0de85 100644 --- a/samples/pushchat/src/main/java/org/onepf/pushchat/ui/fragment/content/MessagesFragment.java +++ b/samples/pushchat/src/main/java/org/onepf/pushchat/ui/fragment/content/MessagesFragment.java @@ -112,6 +112,7 @@ public void onPause() { hideKeyboard(getView()); } + @SuppressWarnings("AssignmentToNull") @Override public void onDestroyView() { super.onDestroyView(); diff --git a/samples/pushchat/src/main/java/org/onepf/pushchat/ui/fragment/content/StateFragment.java b/samples/pushchat/src/main/java/org/onepf/pushchat/ui/fragment/content/StateFragment.java index 0ca7bfde..9bcef3d3 100644 --- a/samples/pushchat/src/main/java/org/onepf/pushchat/ui/fragment/content/StateFragment.java +++ b/samples/pushchat/src/main/java/org/onepf/pushchat/ui/fragment/content/StateFragment.java @@ -23,18 +23,27 @@ import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.text.Editable; +import android.text.TextUtils; +import android.text.TextWatcher; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; +import android.widget.EditText; import android.widget.TextView; +import android.widget.Toast; import org.onepf.opfpush.OPFPush; import org.onepf.opfpush.OPFPushHelper; +import org.onepf.opfpush.gcm.GCMPubSubHelper; import org.onepf.pushchat.R; import org.onepf.pushchat.controller.StateController; import org.onepf.pushchat.model.PushState; +import static android.widget.Toast.LENGTH_SHORT; +import static java.util.Locale.US; import static org.onepf.pushchat.model.PushState.NO_AVAILABLE_PROVIDER; +import static org.onepf.pushchat.model.PushState.REGISTERED; import static org.onepf.pushchat.utils.Constants.PROVIDER_NAME_EXTRA_KEY; import static org.onepf.pushchat.utils.Constants.REGISTERED_ACTION; import static org.onepf.pushchat.utils.Constants.REGISTRATION_ID_EXTRA_KEY; @@ -56,6 +65,13 @@ public class StateFragment extends BaseContentFragment { private Button registerButton; + private EditText topicEditText; + + private Button subscribeButton; + + private Button unsubscribeButton; + + @Nullable private BroadcastReceiver updateStateReceiver; @NonNull @@ -76,8 +92,15 @@ public View onCreateView(@NonNull final LayoutInflater inflater, providerNameTextView = (TextView) view.findViewById(R.id.provider_name_text); registrationIdTextView = (TextView) view.findViewById(R.id.registration_id_text); registerButton = (Button) view.findViewById(R.id.register_button); + topicEditText = (EditText) view.findViewById(R.id.topic_input); + subscribeButton = (Button) view.findViewById(R.id.subscribe_topic_button); + unsubscribeButton = (Button) view.findViewById(R.id.unsubscribe_topic_button); - registerButton.setOnClickListener(onClickListener()); + registerButton.setOnClickListener(onRegistrationClickListener()); + subscribeButton.setOnClickListener(onSubscribeClickListener()); + unsubscribeButton.setOnClickListener(onUnsubscribeClickListener()); + + topicEditText.addTextChangedListener(new TopicTextWatcher()); registerReceiver(); initState(); @@ -85,6 +108,7 @@ public View onCreateView(@NonNull final LayoutInflater inflater, return view; } + @SuppressWarnings("AssignmentToNull") @Override public void onDestroyView() { super.onDestroyView(); @@ -94,6 +118,9 @@ public void onDestroyView() { providerNameTextView = null; registrationIdTextView = null; registerButton = null; + topicEditText = null; + subscribeButton = null; + unsubscribeButton = null; } @Override @@ -138,6 +165,8 @@ private void initRegisteringState() { registrationIdTextView.setVisibility(View.GONE); registerButton.setText(getString(R.string.register_button_text)); registerButton.setEnabled(false); + subscribeButton.setEnabled(false); + unsubscribeButton.setEnabled(false); } private void initRegisteredState(@NonNull final String providerName, @@ -152,6 +181,8 @@ private void initRegisteredState(@NonNull final String providerName, registrationIdTextView.setVisibility(View.VISIBLE); registerButton.setText(getString(R.string.unregister_button_text)); registerButton.setEnabled(true); + subscribeButton.setEnabled(!TextUtils.isEmpty(topicEditText.getText())); + unsubscribeButton.setEnabled(!TextUtils.isEmpty(topicEditText.getText())); } private void initUnregisteredState(final boolean isNoAvailableProvider) { @@ -166,6 +197,8 @@ private void initUnregisteredState(final boolean isNoAvailableProvider) { registrationIdTextView.setVisibility(View.GONE); registerButton.setText(getString(R.string.register_button_text)); registerButton.setEnabled(true); + subscribeButton.setEnabled(false); + unsubscribeButton.setEnabled(false); } private void initUnregisteringState() { @@ -177,6 +210,8 @@ private void initUnregisteringState() { registrationIdTextView.setVisibility(View.GONE); registerButton.setText(getString(R.string.unregister_button_text)); registerButton.setEnabled(false); + subscribeButton.setEnabled(false); + unsubscribeButton.setEnabled(false); } private void registerReceiver() { @@ -215,7 +250,7 @@ public void onReceive(@NonNull final Context context, @NonNull final Intent inte } } - private View.OnClickListener onClickListener() { + private View.OnClickListener onRegistrationClickListener() { return new View.OnClickListener() { @Override public void onClick(View v) { @@ -235,4 +270,105 @@ public void onClick(View v) { } }; } + + private View.OnClickListener onSubscribeClickListener() { + return new View.OnClickListener() { + @Override + public void onClick(View v) { + final Context context = getActivity(); + final String topic = getString(R.string.topic_fmt, topicEditText.getText().toString()); + topicEditText.setText(""); + GCMPubSubHelper.getInstance(context).subscribe( + topic, + null, + new PubSubCallback( + String.format( + US, + "Subscription to topic %s has been performed successfully.", + topic + ), + String.format( + US, + "Subscription to topic %s hasn't been performed.", + topic + ) + ) + ); + } + }; + } + + private View.OnClickListener onUnsubscribeClickListener() { + return new View.OnClickListener() { + @Override + public void onClick(View v) { + final Context context = getActivity(); + final String topic = getString(R.string.topic_fmt, topicEditText.getText().toString()); + topicEditText.setText(""); + GCMPubSubHelper.getInstance(context).unsubscribe( + topic, + new PubSubCallback( + String.format( + US, + "Unsubscribtion from topic %s has been performed successfully.", + topic + ), + String.format( + US, + "Unsubscribtion from topic %s hasn't been performed.", + topic + ) + ) + ); + } + }; + } + + private final class PubSubCallback implements GCMPubSubHelper.Callback { + + @NonNull + private final String successString; + + @NonNull + private final String errorString; + + public PubSubCallback(@NonNull final String successString, + @NonNull final String errorString) { + this.successString = successString; + this.errorString = errorString; + } + + @Override + public void onSuccess() { + Toast.makeText(getActivity(), successString, LENGTH_SHORT).show(); + } + + @Override + public void onError(@Nullable final String error) { + Toast.makeText( + getActivity(), + String.format(US, "%1$s Error message : %2$s", errorString, error), + LENGTH_SHORT + ).show(); + } + } + + private final class TopicTextWatcher implements TextWatcher { + @Override + public void afterTextChanged(final Editable s) { + final boolean isEnabled = !s.toString().isEmpty() && StateController.getState(getActivity()) == REGISTERED; + subscribeButton.setEnabled(isEnabled); + unsubscribeButton.setEnabled(isEnabled); + } + + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + //nothing + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + //nothing + } + } } diff --git a/samples/pushchat/src/main/res/layout/fragment_state.xml b/samples/pushchat/src/main/res/layout/fragment_state.xml index 4e86ba7a..1ea840ab 100644 --- a/samples/pushchat/src/main/res/layout/fragment_state.xml +++ b/samples/pushchat/src/main/res/layout/fragment_state.xml @@ -49,4 +49,32 @@ android:layout_width="match_parent" android:layout_height="wrap_content" /> + + + + +