Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(986)

Unified Diff: chrome/android/java/src/org/chromium/chrome/browser/GcmPlatformImpl.java

Issue 237323002: [NOT FOR REVIEW] Plumb Android GCM to Push API (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | chrome/android/shell/java/AndroidManifest.xml » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/android/java/src/org/chromium/chrome/browser/GcmPlatformImpl.java
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/GcmPlatformImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/GcmPlatformImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..06e4367985f2f5a16cb985fa2c9800ff50c2f060
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/GcmPlatformImpl.java
@@ -0,0 +1,200 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.AsyncTask;
+import android.util.Log;
+
+import com.google.android.gcm.GCMRegistrar;
+import com.google.ipc.invalidation.external.client.contrib.MultiplexingGcmListener;
+
+import org.chromium.base.CalledByNative;
+import org.chromium.base.ThreadUtils;
+
+import java.io.IOException;
+
+/**
+ * This class is the Java counterpart to the C++ GcmPlatformImplAndroid class.
+ * It implements GCM registration, and sends back GCM messages over JNI.
+ *
+ * Threading model note: all calls from C++ must happen on the UI thread.
+ * Callbacks from Android may happen on a different thread, so we always
+ * use ThreadUtils.runOnUiThread when calling back to C++.
+ */
+class GcmPlatformImpl {
+ private static final String TAG = "Chrome-GcmPlatformImpl";
+
+ private static GcmPlatformImpl sInstance = null;
+
+ private long mNativeGcmPlatformImplAndroid;
+ private Context mContext;
+
+ private GcmPlatformImpl(long nativeGcmPlatformImplAndroid, Context context) {
+ mNativeGcmPlatformImplAndroid = nativeGcmPlatformImplAndroid;
+ mContext = context;
+ sInstance = this;
+ }
+
+ /**
+ * Create a GcmPlatformImpl object, which is owned by GcmPlatformImplAndroid
+ * on the C++ side.
+ *
+ * @param nativeGcmPlatformImplAndroid The C++ object that owns us.
+ * @param context The app context.
+ */
+ @CalledByNative
+ private static GcmPlatformImpl create(int nativeGcmPlatformImplAndroid,
+ Context context) {
+ if (sInstance != null) {
+ throw new IllegalStateException("Already instantiated");
+ }
+ return new GcmPlatformImpl(nativeGcmPlatformImplAndroid, context);
+ }
+
+ /**
+ * Called when our C++ counterpart is deleted. Clear the handle to our
+ * native C++ object, ensuring it's never called.
+ */
+ @CalledByNative
+ private void destroy() {
+ mNativeGcmPlatformImplAndroid = 0;
+ }
+
+ /**
+ * Registers the app with GCM servers asynchronously. Calls
+ * nativeOnRegistrationFinished once this is done.
+ *
+ * @param appUniqueIdCurrentlyIgnored A unique string identifying the app.
+ * Currently ignored.
+ * @param senderIds List of project numbers or Google accounts identifying
+ * who is allowed to send messages to this application.
+ */
+ @CalledByNative
+ private void registerApp(String appUniqueIdCurrentlyIgnored, String[] senderIds) {
+ new AsyncTask<String, Void, String>() {
+ @Override
+ protected String doInBackground(String[] senderIds) {
+ try {
+ GCMRegistrar.checkDevice(mContext);
+ }
+ catch (UnsupportedOperationException ex) {
+ return ""; // Indicates failure
+ }
+ GCMRegistrar.checkManifest(mContext); // TODO: Do I want this?
+ String registrationId = GCMRegistrar.getRegistrationId(mContext);
+ if (registrationId.equals("")) {
+ GCMRegistrar.register(mContext, senderIds);
+ return null; // Indicates pending result
+ } else {
+ return registrationId;
+ }
+ }
+
+ @Override
+ protected void onPostExecute(String registrationId) {
+ if (registrationId != null)
+ nativeOnRegistrationFinished(mNativeGcmPlatformImplAndroid,
+ registrationId);
+ }
+ }.execute(senderIds);
+ }
+
+ // registrationId will be an empty string in case of failure.
+ private native void nativeOnRegistrationFinished(long nativeGcmPlatformImplAndroid,
+ String registrationId);
+ private native void nativeOnMessageReceived(long nativeGcmPlatformImplAndroid, String data);
+ private native void nativeOnMessagesDeletedByServer(long nativeGcmPlatformImplAndroid);
+
+ /**
+ * Receives GCM registration events and messages rebroadcast by MultiplexingGcmListener.
+ */
+ public static class GcmListener extends MultiplexingGcmListener.AbstractListener {
+ /**
+ * Receiver for broadcasts by the multiplexed GCM service. It forwards them to
+ * GcmListener.
+ */
+ public static class Receiver extends MultiplexingGcmListener.AbstractListener.Receiver {
+ /**
+ * This class is public so that it can be instantiated by the Android runtime.
+ */
+ @Override
+ protected Class<?> getServiceClass() {
+ return GcmListener.class;
+ }
+ }
+
+ private static final String TAG = "GcmListener";
+
+ public GcmListener() {
+ super(TAG);
+ }
+
+ @Override
+ protected void onMessage(Intent intent) {
+ final GcmPlatformImpl impl = GcmPlatformImpl.sInstance;
+ // HACK FOR DEMO: Don't start Chrome if it's not already running.
+ if (impl == null)
+ return;
+
+ final String DATA_KEY = "data";
+ if (!intent.hasExtra(DATA_KEY)) {
+ // Not a GCM message for us (likely for sync or cloud print).
+ return;
+ }
+ final String data = intent.getExtras().getString(DATA_KEY);
+
+ ThreadUtils.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ impl.nativeOnMessageReceived(impl.mNativeGcmPlatformImplAndroid, data);
+ }
+ });
+ }
+
+ @Override
+ public void onRegistered(final String registrationId) {
+ final GcmPlatformImpl impl = GcmPlatformImpl.sInstance;
+ // Drop this event if it arrives after Chrome gets killed.
+ if (impl == null)
+ return;
+
+ // TODO: Check that this onRegistered event actually corresponds
+ // to the current observer of GcmPlatformImplAndroid. Requires
+ // changes to Android GCM API.
+
+ ThreadUtils.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ impl.nativeOnRegistrationFinished(impl.mNativeGcmPlatformImplAndroid,
+ registrationId);
+ }
+ });
+ }
+
+ @Override
+ public void onUnregistered(String registrationId) {
+ Log.e(TAG, "onUnregistered not implemented");
+ }
+
+ @Override
+ protected void onDeletedMessages(int total) {
+ final GcmPlatformImpl impl = GcmPlatformImpl.sInstance;
+ // HACK FOR DEMO: Don't start Chrome if it's not already running.
+ if (impl == null)
+ return;
+
+ // FIXME: How do we know whether this message is for us, sync or cloud print?
+
+ ThreadUtils.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ impl.nativeOnMessagesDeletedByServer(impl.mNativeGcmPlatformImplAndroid);
+ }
+ });
+ }
+ }
+}
« no previous file with comments | « no previous file | chrome/android/shell/java/AndroidManifest.xml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698