From bfe85e85139e6d7bd176cea045bfa2f44835f534 Mon Sep 17 00:00:00 2001 From: maniac103 <dannybaumann@web.de> Date: Sat, 25 Aug 2018 11:12:50 +0200 Subject: [PATCH] Convert GcmRegistrationService to a JobIntentService. (#980) * Convert GcmRegistrationService to a JobIntentService. Otherwise crashes might occur when app is in the background and connectivity changes on Android 8+. Fixes #953 Signed-off-by: Danny Baumann <dannybaumann@web.de> * Consistently schedule GcmRegistrationService via enqueueWork(). Signed-off-by: Danny Baumann <dannybaumann@web.de> * Refactor all invocations of GcmRegistrationService for JobIntentService. Signed-off-by: Danny Baumann <dannybaumann@web.de> * Override CloudMessagingHelper for test. We don't want to include the complexity of the full flavor CloudMessagingHelper in the ConnectionFactoryTest. Signed-off-by: Danny Baumann <dannybaumann@web.de> --- mobile/src/full/AndroidManifest.xml | 9 ++- .../habdroid/core/CloudMessagingHelper.java | 9 +-- .../core/GcmInstanceIDListenerService.java | 6 +- .../core/GcmMessageListenerService.java | 13 +---- .../habdroid/core/GcmRegistrationService.java | 56 ++++++++++++++++--- .../habdroid/core/CloudMessagingHelper.java | 32 +++++++++++ 6 files changed, 92 insertions(+), 33 deletions(-) create mode 100644 mobile/src/test/java/org/openhab/habdroid/core/CloudMessagingHelper.java diff --git a/mobile/src/full/AndroidManifest.xml b/mobile/src/full/AndroidManifest.xml index 18d41663..bdc4a220 100644 --- a/mobile/src/full/AndroidManifest.xml +++ b/mobile/src/full/AndroidManifest.xml @@ -14,6 +14,13 @@ </intent-filter> </receiver> + <receiver + android:name="org.openhab.habdroid.core.GcmRegistrationService$ProxyReceiver"> + <intent-filter> + <action android:name="org.openhab.habdroid.action.HIDE_NOTIFICATION" /> + </intent-filter> + </receiver> + <service android:name="org.openhab.habdroid.core.GcmMessageListenerService" android:exported="false"> @@ -32,7 +39,7 @@ <service android:name="org.openhab.habdroid.core.GcmRegistrationService" - android:exported="false" /> + android:permission="android.permission.BIND_JOB_SERVICE" /> <meta-data android:name="com.google.android.gms.version" diff --git a/mobile/src/full/java/org/openhab/habdroid/core/CloudMessagingHelper.java b/mobile/src/full/java/org/openhab/habdroid/core/CloudMessagingHelper.java index c9d7ec22..e6f0f225 100644 --- a/mobile/src/full/java/org/openhab/habdroid/core/CloudMessagingHelper.java +++ b/mobile/src/full/java/org/openhab/habdroid/core/CloudMessagingHelper.java @@ -25,19 +25,14 @@ public class CloudMessagingHelper { public static void onConnectionUpdated(Context context, CloudConnection connection) { sRegistrationDone = false; if (connection != null) { - Intent intent = new Intent(context, GcmRegistrationService.class) - .setAction(GcmRegistrationService.ACTION_REGISTER); - context.startService(intent); + GcmRegistrationService.scheduleRegistration(context); } } public static void onNotificationSelected(Context context, Intent intent) { int notificationId = intent.getIntExtra(GcmMessageListenerService.EXTRA_NOTIFICATION_ID, -1); if (notificationId >= 0) { - Intent serviceIntent = new Intent(context, GcmRegistrationService.class) - .setAction(GcmRegistrationService.ACTION_HIDE_NOTIFICATION) - .putExtra(GcmRegistrationService.EXTRA_NOTIFICATION_ID, notificationId); - context.startService(serviceIntent); + GcmRegistrationService.scheduleHideNotification(context, notificationId); } } diff --git a/mobile/src/full/java/org/openhab/habdroid/core/GcmInstanceIDListenerService.java b/mobile/src/full/java/org/openhab/habdroid/core/GcmInstanceIDListenerService.java index 91467a6b..4097be0f 100644 --- a/mobile/src/full/java/org/openhab/habdroid/core/GcmInstanceIDListenerService.java +++ b/mobile/src/full/java/org/openhab/habdroid/core/GcmInstanceIDListenerService.java @@ -9,15 +9,11 @@ package org.openhab.habdroid.core; -import android.content.Intent; - import com.google.android.gms.iid.InstanceIDListenerService; public class GcmInstanceIDListenerService extends InstanceIDListenerService { @Override public void onTokenRefresh() { - Intent intent = new Intent(this, GcmRegistrationService.class) - .setAction(GcmRegistrationService.ACTION_REGISTER); - startService(intent); + GcmRegistrationService.scheduleRegistration(this); } } diff --git a/mobile/src/full/java/org/openhab/habdroid/core/GcmMessageListenerService.java b/mobile/src/full/java/org/openhab/habdroid/core/GcmMessageListenerService.java index f9c62ed4..5e2f94d0 100644 --- a/mobile/src/full/java/org/openhab/habdroid/core/GcmMessageListenerService.java +++ b/mobile/src/full/java/org/openhab/habdroid/core/GcmMessageListenerService.java @@ -116,15 +116,6 @@ public class GcmMessageListenerService extends GcmListenerService { contentIntent, PendingIntent.FLAG_UPDATE_CURRENT); } - private PendingIntent makeDeleteIntent(int notificationId) { - Intent deleteIntent = new Intent(this, GcmRegistrationService.class) - .setAction(GcmRegistrationService.ACTION_HIDE_NOTIFICATION) - .putExtra(GcmRegistrationService.EXTRA_NOTIFICATION_ID, notificationId); - - return PendingIntent.getService(this, notificationId, - deleteIntent, PendingIntent.FLAG_UPDATE_CURRENT); - } - private Notification makeNotification(String msg, String channelId, String icon, long timestamp, String persistedId, int notificationId) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); @@ -158,7 +149,7 @@ public class GcmMessageListenerService extends GcmListenerService { .setSound(Uri.parse(toneSetting)) .setContentText(msg) .setContentIntent(contentIntent) - .setDeleteIntent(makeDeleteIntent(notificationId)) + .setDeleteIntent(GcmRegistrationService.createHideNotificationIntent(this, notificationId)) .setVisibility(NotificationCompat.VISIBILITY_PRIVATE) .setPublicVersion(publicVersion) .build(); @@ -181,7 +172,7 @@ public class GcmMessageListenerService extends GcmListenerService { .setContentText(text) .setPublicVersion(publicVersion) .setContentIntent(clickIntent) - .setDeleteIntent(makeDeleteIntent(SUMMARY_NOTIFICATION_ID)) + .setDeleteIntent(GcmRegistrationService.createHideNotificationIntent(this, SUMMARY_NOTIFICATION_ID)) .build(); } diff --git a/mobile/src/full/java/org/openhab/habdroid/core/GcmRegistrationService.java b/mobile/src/full/java/org/openhab/habdroid/core/GcmRegistrationService.java index 2e541da0..16eaaf20 100644 --- a/mobile/src/full/java/org/openhab/habdroid/core/GcmRegistrationService.java +++ b/mobile/src/full/java/org/openhab/habdroid/core/GcmRegistrationService.java @@ -9,12 +9,15 @@ package org.openhab.habdroid.core; -import android.app.IntentService; +import android.app.PendingIntent; +import android.content.BroadcastReceiver; +import android.content.Context; import android.content.Intent; import android.os.Build; import android.os.Bundle; import android.provider.Settings; -import android.support.annotation.Nullable; +import android.support.annotation.NonNull; +import android.support.v4.app.JobIntentService; import android.util.Log; import com.google.android.gms.gcm.GoogleCloudMessaging; @@ -29,19 +32,39 @@ import java.io.IOException; import java.net.URLEncoder; import java.util.Locale; -public class GcmRegistrationService extends IntentService { +public class GcmRegistrationService extends JobIntentService { private static final String TAG = GcmRegistrationService.class.getSimpleName(); - static final String ACTION_REGISTER = "org.openhab.habdroid.action.REGISTER_GCM"; - static final String ACTION_HIDE_NOTIFICATION = "org.openhab.habdroid.action.HIDE_NOTIFICATION"; - static final String EXTRA_NOTIFICATION_ID = "notificationId"; + private static final int JOB_ID = 1000; - public GcmRegistrationService() { - super("GcmRegistrationService"); + private static final String ACTION_REGISTER = "org.openhab.habdroid.action.REGISTER_GCM"; + private static final String ACTION_HIDE_NOTIFICATION = "org.openhab.habdroid.action.HIDE_NOTIFICATION"; + private static final String EXTRA_NOTIFICATION_ID = "notificationId"; + + static void scheduleRegistration(Context context) { + Intent intent = new Intent(context, GcmRegistrationService.class) + .setAction(GcmRegistrationService.ACTION_REGISTER); + JobIntentService.enqueueWork(context, GcmRegistrationService.class, JOB_ID, intent); + } + + static void scheduleHideNotification(Context context, int notificationId) { + JobIntentService.enqueueWork(context, GcmRegistrationService.class, JOB_ID, + makeHideNotificationIntent(context, notificationId)); + } + + static PendingIntent createHideNotificationIntent(Context context, int notificationId) { + return ProxyReceiver.wrap(context, makeHideNotificationIntent(context, notificationId), + notificationId); + } + + private static Intent makeHideNotificationIntent(Context context, int notificationId) { + return new Intent(context, GcmRegistrationService.class) + .setAction(GcmRegistrationService.ACTION_HIDE_NOTIFICATION) + .putExtra(GcmRegistrationService.EXTRA_NOTIFICATION_ID, notificationId); } @Override - protected void onHandleIntent(@Nullable Intent intent) { + protected void onHandleWork(@NonNull Intent intent) { ConnectionFactory.waitForInitialization(); CloudConnection connection = (CloudConnection) ConnectionFactory.getConnection(Connection.TYPE_CLOUD); @@ -104,4 +127,19 @@ public class GcmRegistrationService extends IntentService { sendBundle.putString("notificationId", String.valueOf(notificationId)); gcm.send(senderId + "@gcm.googleapis.com", "1", sendBundle); } + + public static class ProxyReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + Intent actual = intent.getParcelableExtra("intent"); + JobIntentService.enqueueWork(context, GcmRegistrationService.class, JOB_ID, actual); + } + + private static PendingIntent wrap(Context context, Intent intent, int id) { + Intent wrapped = new Intent(context, ProxyReceiver.class) + .putExtra("intent", intent); + return PendingIntent.getBroadcast(context, id, + wrapped, PendingIntent.FLAG_UPDATE_CURRENT); + } + } } diff --git a/mobile/src/test/java/org/openhab/habdroid/core/CloudMessagingHelper.java b/mobile/src/test/java/org/openhab/habdroid/core/CloudMessagingHelper.java new file mode 100644 index 00000000..ef54577a --- /dev/null +++ b/mobile/src/test/java/org/openhab/habdroid/core/CloudMessagingHelper.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2010-2018, openHAB.org and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ + +package org.openhab.habdroid.core; + +import android.content.Context; +import android.content.Intent; +import android.support.annotation.StringRes; + +import org.openhab.habdroid.core.connection.CloudConnection; + +public class CloudMessagingHelper { + public static void onConnectionUpdated(Context context, CloudConnection connection) { + } + + public static void onNotificationSelected(Context context, Intent intent) { + } + + public static @StringRes int getPushNotificationStatusResId() { + return 0; + } + + public static boolean isSupported() { + return false; + } +} -- GitLab