Index: components/gcm_driver/android/java/src/org/chromium/components/gcm_driver/GCMDriver.java |
diff --git a/components/gcm_driver/android/java/src/org/chromium/components/gcm_driver/GCMDriver.java b/components/gcm_driver/android/java/src/org/chromium/components/gcm_driver/GCMDriver.java |
index f8d70ce03e2232df0756c436165988b242dc32a1..b7a50242d259c521a08bfb8f934c0aab7a430112 100644 |
--- a/components/gcm_driver/android/java/src/org/chromium/components/gcm_driver/GCMDriver.java |
+++ b/components/gcm_driver/android/java/src/org/chromium/components/gcm_driver/GCMDriver.java |
@@ -5,7 +5,11 @@ |
package org.chromium.components.gcm_driver; |
import android.content.Context; |
+import android.os.AsyncTask; |
import android.os.Bundle; |
+import android.util.Log; |
+ |
+import com.google.android.gcm.GCMRegistrar; |
import org.chromium.base.CalledByNative; |
import org.chromium.base.JNINamespace; |
@@ -15,11 +19,16 @@ import java.util.ArrayList; |
import java.util.List; |
/** |
- * An implementation of GCMDriver using Android's Java GCM APIs. |
+ * This class is the Java counterpart to the C++ GCMDriverAndroid class. |
+ * It uses Android's Java GCM APIs to implements GCM registration etc, and |
+ * sends back GCM messages over JNI. |
+ * |
* Threading model: all calls to/from C++ happen on the UI thread. |
*/ |
@JNINamespace("gcm") |
-public final class GCMDriver { |
+public class GCMDriver { |
+ private static final String TAG = "GCMDriver"; |
+ |
// The instance of GCMDriver currently owned by a C++ GCMDriverAndroid, if any. |
private static GCMDriver sInstance = null; |
@@ -41,8 +50,9 @@ public final class GCMDriver { |
@CalledByNative |
private static GCMDriver create(long nativeGCMDriverAndroid, |
Context context) { |
- if (sInstance != null) |
+ if (sInstance != null) { |
throw new IllegalStateException("Already instantiated"); |
+ } |
sInstance = new GCMDriver(nativeGCMDriverAndroid, context); |
return sInstance; |
} |
@@ -59,32 +69,91 @@ public final class GCMDriver { |
} |
@CalledByNative |
- private void register(String appId, String[] senderIds) { |
- // TODO(johnme): Actually try to register. |
- nativeOnRegisterFinished(mNativeGCMDriverAndroid, appId, "", false); |
+ private void register(final String appId, final String[] senderIds) { |
+ new AsyncTask<Void, Void, String>() { |
+ @Override |
+ protected String doInBackground(Void... voids) { |
+ try { |
+ GCMRegistrar.checkDevice(mContext); |
+ } catch (UnsupportedOperationException ex) { |
+ return ""; // Indicates failure. |
+ } |
+ // TODO(johnme): Move checkManifest call to a test instead. |
+ GCMRegistrar.checkManifest(mContext); |
+ String existingRegistrationId = GCMRegistrar.getRegistrationId(mContext); |
+ if (existingRegistrationId.equals("")) { |
+ // TODO(johnme): Migrate from GCMRegistrar to GoogleCloudMessaging API, both |
+ // here and elsewhere in Chromium. |
+ // TODO(johnme): Pass appId to GCM. |
+ GCMRegistrar.register(mContext, senderIds); |
+ return null; // Indicates pending result. |
+ } else { |
+ Log.i(TAG, "Re-using existing registration ID"); |
+ return existingRegistrationId; |
+ } |
+ } |
+ @Override |
+ protected void onPostExecute(String registrationId) { |
+ if (registrationId == null) { |
+ return; // Wait for {@link #onRegisterFinished} to be called. |
+ } |
+ nativeOnRegisterFinished(mNativeGCMDriverAndroid, appId, registrationId, |
+ !registrationId.isEmpty()); |
+ } |
+ }.execute(); |
} |
+ |
+ private enum UnregisterResult { SUCCESS, FAILED, PENDING } |
+ |
@CalledByNative |
- private void unregister(String appId) { |
- // TODO(johnme): Actually try to unregister. |
- nativeOnUnregisterFinished(mNativeGCMDriverAndroid, appId, false); |
+ private void unregister(final String appId) { |
+ new AsyncTask<Void, Void, UnregisterResult>() { |
+ @Override |
+ protected UnregisterResult doInBackground(Void... voids) { |
+ try { |
+ GCMRegistrar.checkDevice(mContext); |
+ } catch (UnsupportedOperationException ex) { |
+ return UnregisterResult.FAILED; |
+ } |
+ if (!GCMRegistrar.isRegistered(mContext)) { |
+ return UnregisterResult.SUCCESS; |
+ } |
+ // TODO(johnme): Pass appId to GCM. |
+ GCMRegistrar.unregister(mContext); |
+ return UnregisterResult.PENDING; |
+ } |
+ |
+ @Override |
+ protected void onPostExecute(UnregisterResult result) { |
+ if (result == UnregisterResult.PENDING) { |
+ return; // Wait for {@link #onUnregisterFinished} to be called. |
+ } |
+ nativeOnUnregisterFinished(mNativeGCMDriverAndroid, appId, |
+ result == UnregisterResult.SUCCESS); |
+ } |
+ }.execute(); |
} |
- public static void onRegistered(String appId, String registrationId) { |
+ static void onRegisterFinished(String appId, String registrationId) { |
ThreadUtils.assertOnUiThread(); |
+ // TODO(johnme): If this gets called, did it definitely succeed? |
// TODO(johnme): Update registrations cache? |
- if (sInstance != null) |
+ if (sInstance != null) { |
sInstance.nativeOnRegisterFinished(sInstance.mNativeGCMDriverAndroid, appId, |
registrationId, true); |
+ } |
} |
- public static void onUnregistered(String appId) { |
+ static void onUnregisterFinished(String appId) { |
ThreadUtils.assertOnUiThread(); |
+ // TODO(johnme): If this gets called, did it definitely succeed? |
// TODO(johnme): Update registrations cache? |
- if (sInstance != null) |
+ if (sInstance != null) { |
sInstance.nativeOnUnregisterFinished(sInstance.mNativeGCMDriverAndroid, appId, true); |
+ } |
} |
- public static void onMessageReceived(final String appId, final Bundle extras) { |
+ static void onMessageReceived(final String appId, final Bundle extras) { |
// TODO(johnme): Store message and redeliver later if Chrome is killed before delivery. |
ThreadUtils.assertOnUiThread(); |
launchNativeThen(new Runnable() { |
@@ -113,7 +182,7 @@ public final class GCMDriver { |
}); |
} |
- public static void onMessagesDeleted(final String appId) { |
+ static void onMessagesDeleted(final String appId) { |
// TODO(johnme): Store event and redeliver later if Chrome is killed before delivery. |
ThreadUtils.assertOnUiThread(); |
launchNativeThen(new Runnable() { |