Index: chrome/android/java/src/org/chromium/chrome/browser/services/gcm/ChromeGcmListenerService.java |
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/ChromeGcmListenerService.java b/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/ChromeGcmListenerService.java |
index d1a1660be5a4a59c13edd1a4acf117f01a0f9ee0..41dd270853731c43401da1316ee962854653bd8e 100644 |
--- a/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/ChromeGcmListenerService.java |
+++ b/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/ChromeGcmListenerService.java |
@@ -4,6 +4,11 @@ |
package org.chromium.chrome.browser.services.gcm; |
+import android.app.job.JobInfo; |
+import android.app.job.JobScheduler; |
+import android.content.ComponentName; |
+import android.content.Context; |
+import android.os.Build; |
import android.os.Bundle; |
import android.text.TextUtils; |
@@ -14,9 +19,11 @@ import org.chromium.base.Log; |
import org.chromium.base.ThreadUtils; |
import org.chromium.base.annotations.SuppressFBWarnings; |
import org.chromium.base.library_loader.ProcessInitException; |
+import org.chromium.chrome.browser.JobSchedulerConstants; |
import org.chromium.chrome.browser.init.ChromeBrowserInitializer; |
import org.chromium.chrome.browser.init.ProcessInitializationHandler; |
import org.chromium.components.gcm_driver.GCMDriver; |
+import org.chromium.components.gcm_driver.GCMMessage; |
/** |
* Receives Downstream messages and status of upstream messages from GCM. |
@@ -40,7 +47,17 @@ public class ChromeGcmListenerService extends GcmListenerService { |
AndroidGcmController.get(this).onMessageReceived(data); |
return; |
} |
- pushMessageReceived(from, data); |
+ |
+ GCMMessage message = null; |
+ try { |
+ message = new GCMMessage(from, data); |
+ } catch (IllegalArgumentException e) { |
+ Log.e(TAG, "Received an invalid GCM Message", e); |
+ return; |
+ } |
+ |
+ // Dispatch the message to the GCM Driver for native features. |
+ scheduleOrDispatchMessageToDriver(getApplicationContext(), message); |
} |
@Override |
@@ -63,28 +80,51 @@ public class ChromeGcmListenerService extends GcmListenerService { |
GcmUma.recordDeletedMessages(getApplicationContext()); |
} |
- private void pushMessageReceived(final String from, final Bundle data) { |
- final String bundleSubtype = "subtype"; |
- if (!data.containsKey(bundleSubtype)) { |
- Log.w(TAG, "Received push message with no subtype"); |
- return; |
- } |
- final String appId = data.getString(bundleSubtype); |
- ThreadUtils.runOnUiThread(new Runnable() { |
- @Override |
- @SuppressFBWarnings("DM_EXIT") |
- public void run() { |
- try { |
- ChromeBrowserInitializer.getInstance(getApplicationContext()) |
- .handleSynchronousStartup(); |
- GCMDriver.onMessageReceived(appId, from, data); |
- } catch (ProcessInitException e) { |
- Log.e(TAG, "ProcessInitException while starting the browser process"); |
- // Since the library failed to initialize nothing in the application |
- // can work, so kill the whole application not just the activity. |
- System.exit(-1); |
+ /** |
+ * Either schedules |message| to be dispatched through the Job Scheduler, which we use on |
+ * Android N and beyond, or immediately dispatches the message on other versions of Android. |
+ */ |
+ static void scheduleOrDispatchMessageToDriver(final Context context, final GCMMessage message) { |
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { |
+ // TODO(peter): Add UMA for measuring latency introduced by the JobScheduler. |
+ JobInfo job = new JobInfo |
+ .Builder(JobSchedulerConstants.GCM_DRIVER_JOB_ID, |
+ new ComponentName(context, GCMJobService.class)) |
+ .setExtras(message.toPersistableBundle()) |
+ .setOverrideDeadline(0) |
+ .build(); |
+ JobScheduler scheduler = |
+ (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); |
+ scheduler.schedule(job); |
+ } else { |
+ ThreadUtils.runOnUiThread(new Runnable() { |
+ @Override |
+ public void run() { |
+ ChromeGcmListenerService.dispatchMessageToDriver(context, message); |
} |
- } |
- }); |
+ }); |
+ } |
+ } |
+ |
+ /** |
+ * To be called when a GCM message is ready to be dispatched. Will initialise the native code |
+ * of the browser process, and forward the message to the GCM Driver. Must be called on the UI |
+ * thread. |
+ */ |
+ @SuppressFBWarnings("DM_EXIT") |
+ static void dispatchMessageToDriver(Context applicationContext, GCMMessage message) { |
+ ThreadUtils.assertOnUiThread(); |
+ |
+ try { |
+ ChromeBrowserInitializer.getInstance(applicationContext).handleSynchronousStartup(); |
+ GCMDriver.dispatchMessage(message); |
+ |
+ } catch (ProcessInitException e) { |
+ Log.e(TAG, "ProcessInitException while starting the browser process"); |
+ |
+ // Since the library failed to initialize nothing in the application can work, so kill |
+ // the whole application as opposed to just this service. |
+ System.exit(-1); |
+ } |
} |
} |