Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.chrome.browser.services.gcm; | 5 package org.chromium.chrome.browser.services.gcm; |
| 6 | 6 |
| 7 import android.app.job.JobInfo; | |
| 8 import android.app.job.JobScheduler; | |
| 9 import android.content.ComponentName; | |
| 10 import android.content.Context; | |
| 11 import android.os.Build; | |
| 7 import android.os.Bundle; | 12 import android.os.Bundle; |
| 8 import android.text.TextUtils; | 13 import android.text.TextUtils; |
| 9 | 14 |
| 10 import com.google.android.gms.gcm.GcmListenerService; | 15 import com.google.android.gms.gcm.GcmListenerService; |
| 11 import com.google.ipc.invalidation.ticl.android2.channel.AndroidGcmController; | 16 import com.google.ipc.invalidation.ticl.android2.channel.AndroidGcmController; |
| 12 | 17 |
| 13 import org.chromium.base.Log; | 18 import org.chromium.base.Log; |
| 14 import org.chromium.base.ThreadUtils; | 19 import org.chromium.base.ThreadUtils; |
| 15 import org.chromium.base.annotations.SuppressFBWarnings; | 20 import org.chromium.base.annotations.SuppressFBWarnings; |
| 16 import org.chromium.base.library_loader.ProcessInitException; | 21 import org.chromium.base.library_loader.ProcessInitException; |
| 22 import org.chromium.chrome.browser.JobSchedulerConstants; | |
| 17 import org.chromium.chrome.browser.init.ChromeBrowserInitializer; | 23 import org.chromium.chrome.browser.init.ChromeBrowserInitializer; |
| 18 import org.chromium.chrome.browser.init.ProcessInitializationHandler; | 24 import org.chromium.chrome.browser.init.ProcessInitializationHandler; |
| 19 import org.chromium.components.gcm_driver.GCMDriver; | 25 import org.chromium.components.gcm_driver.GCMDriver; |
| 26 import org.chromium.components.gcm_driver.GCMMessage; | |
| 20 | 27 |
| 21 /** | 28 /** |
| 22 * Receives Downstream messages and status of upstream messages from GCM. | 29 * Receives Downstream messages and status of upstream messages from GCM. |
| 23 */ | 30 */ |
| 24 public class ChromeGcmListenerService extends GcmListenerService { | 31 public class ChromeGcmListenerService extends GcmListenerService { |
| 25 private static final String TAG = "ChromeGcmListener"; | 32 private static final String TAG = "ChromeGcmListener"; |
| 26 | 33 |
| 27 @Override | 34 @Override |
| 28 public void onCreate() { | 35 public void onCreate() { |
| 29 ProcessInitializationHandler.getInstance().initializePreNative(); | 36 ProcessInitializationHandler.getInstance().initializePreNative(); |
| 30 super.onCreate(); | 37 super.onCreate(); |
| 31 } | 38 } |
| 32 | 39 |
| 33 @Override | 40 @Override |
| 34 public void onMessageReceived(String from, Bundle data) { | 41 public void onMessageReceived(String from, Bundle data) { |
| 35 boolean hasCollapseKey = !TextUtils.isEmpty(data.getString("collapse_key ")); | 42 boolean hasCollapseKey = !TextUtils.isEmpty(data.getString("collapse_key ")); |
| 36 GcmUma.recordDataMessageReceived(getApplicationContext(), hasCollapseKey ); | 43 GcmUma.recordDataMessageReceived(getApplicationContext(), hasCollapseKey ); |
| 37 | 44 |
| 38 String invalidationSenderId = AndroidGcmController.get(this).getSenderId (); | 45 String invalidationSenderId = AndroidGcmController.get(this).getSenderId (); |
| 39 if (from.equals(invalidationSenderId)) { | 46 if (from.equals(invalidationSenderId)) { |
| 40 AndroidGcmController.get(this).onMessageReceived(data); | 47 AndroidGcmController.get(this).onMessageReceived(data); |
| 41 return; | 48 return; |
| 42 } | 49 } |
| 43 pushMessageReceived(from, data); | 50 |
| 51 // Dispatch the message to the GCM Driver for native features. | |
| 52 scheduleOrDispatchMessageToDriver(getApplicationContext(), from, data); | |
| 44 } | 53 } |
| 45 | 54 |
| 46 @Override | 55 @Override |
| 47 public void onMessageSent(String msgId) { | 56 public void onMessageSent(String msgId) { |
| 48 Log.d(TAG, "Message sent successfully. Message id: " + msgId); | 57 Log.d(TAG, "Message sent successfully. Message id: " + msgId); |
| 49 GcmUma.recordGcmUpstreamHistogram(getApplicationContext(), GcmUma.UMA_UP STREAM_SUCCESS); | 58 GcmUma.recordGcmUpstreamHistogram(getApplicationContext(), GcmUma.UMA_UP STREAM_SUCCESS); |
| 50 } | 59 } |
| 51 | 60 |
| 52 @Override | 61 @Override |
| 53 public void onSendError(String msgId, String error) { | 62 public void onSendError(String msgId, String error) { |
| 54 Log.w(TAG, "Error in sending message. Message id: " + msgId + " Error: " + error); | 63 Log.w(TAG, "Error in sending message. Message id: " + msgId + " Error: " + error); |
| 55 GcmUma.recordGcmUpstreamHistogram(getApplicationContext(), GcmUma.UMA_UP STREAM_SEND_FAILED); | 64 GcmUma.recordGcmUpstreamHistogram(getApplicationContext(), GcmUma.UMA_UP STREAM_SEND_FAILED); |
| 56 } | 65 } |
| 57 | 66 |
| 58 @Override | 67 @Override |
| 59 public void onDeletedMessages() { | 68 public void onDeletedMessages() { |
| 60 // TODO(johnme): Ask GCM to include the subtype in this event. | 69 // TODO(johnme): Ask GCM to include the subtype in this event. |
| 61 Log.w(TAG, "Push messages were deleted, but we can't tell the Service Wo rker as we don't" | 70 Log.w(TAG, "Push messages were deleted, but we can't tell the Service Wo rker as we don't" |
| 62 + "know what subtype (app ID) it occurred for."); | 71 + "know what subtype (app ID) it occurred for."); |
| 63 GcmUma.recordDeletedMessages(getApplicationContext()); | 72 GcmUma.recordDeletedMessages(getApplicationContext()); |
| 64 } | 73 } |
| 65 | 74 |
| 66 private void pushMessageReceived(final String from, final Bundle data) { | 75 /** |
| 67 final String bundleSubtype = "subtype"; | 76 * To be called when a GCM message is ready to be dispatched. Will initialis e the native code |
| 68 if (!data.containsKey(bundleSubtype)) { | 77 * of the browser process, and forward the message to the GCM Driver. |
|
awdf
2017/02/16 21:26:48
nit: could add "Must be called on the UI thread."
Peter Beverloo
2017/02/17 15:43:59
Done.
| |
| 69 Log.w(TAG, "Received push message with no subtype"); | 78 */ |
| 70 return; | 79 @SuppressFBWarnings("DM_EXIT") |
| 80 public static void dispatchMessageToDriver(Context applicationContext, GCMMe ssage message) { | |
|
awdf
2017/02/16 21:26:48
nit: can you make this method default (package) pr
Peter Beverloo
2017/02/17 15:43:59
Done.
| |
| 81 ThreadUtils.assertOnUiThread(); | |
| 82 | |
| 83 try { | |
| 84 ChromeBrowserInitializer.getInstance(applicationContext).handleSynch ronousStartup(); | |
| 85 GCMDriver.dispatchMessage(message); | |
| 86 | |
| 87 } catch (ProcessInitException e) { | |
| 88 Log.e(TAG, "ProcessInitException while starting the browser process" ); | |
| 89 | |
| 90 // Since the library failed to initialize nothing in the application can work, so kill | |
| 91 // the whole application as opposed to just this service. | |
| 92 System.exit(-1); | |
| 71 } | 93 } |
| 72 final String appId = data.getString(bundleSubtype); | 94 } |
| 73 ThreadUtils.runOnUiThread(new Runnable() { | 95 |
| 74 @Override | 96 /** |
| 75 @SuppressFBWarnings("DM_EXIT") | 97 * Either schedules |message| to be dispatched through the Job Scheduler, wh ich we use on |
| 76 public void run() { | 98 * Android N and beyond, or immediately dispatches the message on other vers ions of Android. |
| 77 try { | 99 */ |
| 78 ChromeBrowserInitializer.getInstance(getApplicationContext() ) | 100 public static void scheduleOrDispatchMessageToDriver( |
|
awdf
2017/02/16 21:26:48
nit: place this method above dispatchMessageToDriv
Peter Beverloo
2017/02/17 15:43:59
Done. Why?
awdf
2017/02/18 07:51:41
because this one calls dispatchMessageToDrive so l
| |
| 79 .handleSynchronousStartup(); | 101 final Context context, String senderId, Bundle extras) { |
| 80 GCMDriver.onMessageReceived(appId, from, data); | 102 final GCMMessage message = new GCMMessage(senderId, extras); |
| 81 } catch (ProcessInitException e) { | 103 |
| 82 Log.e(TAG, "ProcessInitException while starting the browser process"); | 104 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { |
|
awdf
2017/02/16 21:26:48
nit: I'm wondering if we should have a common shou
Peter Beverloo
2017/02/17 15:43:59
I think that'll depend on the feature, doesn't it?
| |
| 83 // Since the library failed to initialize nothing in the app lication | 105 // TODO(peter): Add UMA for measuring latency introduced by the JobS cheduler. |
| 84 // can work, so kill the whole application not just the acti vity. | 106 JobInfo job = new JobInfo |
| 85 System.exit(-1); | 107 .Builder(JobSchedulerConstants.GCM_DRIVER_JOB_ ID, |
| 108 new ComponentName(context, GCMJobServi ce.class)) | |
| 109 .setExtras(message.toPersistableBundle()) | |
| 110 .setOverrideDeadline(0) | |
| 111 .build(); | |
| 112 JobScheduler scheduler = | |
| 113 (JobScheduler) context.getSystemService(Context.JOB_SCHEDULE R_SERVICE); | |
| 114 scheduler.schedule(job); | |
| 115 } else { | |
| 116 ThreadUtils.runOnUiThread(new Runnable() { | |
| 117 @Override | |
| 118 public void run() { | |
| 119 ChromeGcmListenerService.dispatchMessageToDriver(context, me ssage); | |
| 86 } | 120 } |
| 87 } | 121 }); |
| 88 }); | 122 } |
| 89 } | 123 } |
| 90 } | 124 } |
| OLD | NEW |