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

Unified Diff: components/gcm_driver/android/java/src/org/chromium/components/gcm_driver/GCMMessage.java

Issue 2690163008: Route through a JobService when receiving a message for the GCM Driver (Closed)
Patch Set: Comments and build fix Created 3 years, 10 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
Index: components/gcm_driver/android/java/src/org/chromium/components/gcm_driver/GCMMessage.java
diff --git a/components/gcm_driver/android/java/src/org/chromium/components/gcm_driver/GCMMessage.java b/components/gcm_driver/android/java/src/org/chromium/components/gcm_driver/GCMMessage.java
new file mode 100644
index 0000000000000000000000000000000000000000..d696b2e6d84c09142da98b895c728bc58066baa1
--- /dev/null
+++ b/components/gcm_driver/android/java/src/org/chromium/components/gcm_driver/GCMMessage.java
@@ -0,0 +1,166 @@
+// Copyright 2017 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.components.gcm_driver;
+
+import android.annotation.TargetApi;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.PersistableBundle;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.annotation.Nullable;
+
+/**
+ * Represents the contents of a GCM Message that is to be handled by the GCM Driver. Can be created
+ * based on data received from GCM, or serialized and deserialized to and from a PersistableBundle.
+ */
+public class GCMMessage {
+ /**
+ * Keys used to store information in the persistable bundle for serialization purposes.
+ */
+ private static final String BUNDLE_KEY_APP_ID = "appId";
+ private static final String BUNDLE_KEY_COLLAPSE_KEY = "collapseKey";
+ private static final String BUNDLE_KEY_DATA = "data";
+ private static final String BUNDLE_KEY_RAW_DATA = "rawData";
+ private static final String BUNDLE_KEY_SENDER_ID = "senderId";
+
+ private String mSenderId;
+ private String mAppId;
+
+ @Nullable
+ private String mCollapseKey;
+ @Nullable
+ private byte[] mRawData;
+
+ /**
+ * Array that contains pairs of entries in the format of {key, value}.
+ */
+ private String[] mDataKeysAndValuesArray;
+
+ /**
+ * Validates that all required fields have been set in the given bundle.
+ */
+ @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+ public static boolean validatePersistableBundle(PersistableBundle persistableBundle) {
+ return persistableBundle.containsKey(BUNDLE_KEY_APP_ID)
+ && persistableBundle.containsKey(BUNDLE_KEY_COLLAPSE_KEY)
+ && persistableBundle.containsKey(BUNDLE_KEY_DATA)
+ && persistableBundle.containsKey(BUNDLE_KEY_RAW_DATA)
+ && persistableBundle.containsKey(BUNDLE_KEY_SENDER_ID);
+ }
+
+ /**
+ * Creates a GCMMessage object based on data received from GCM. The extras will be filtered.
+ */
+ public GCMMessage(String senderId, Bundle extras) {
+ final String bundleCollapseKey = "collapse_key";
+ final String bundleGcmplex = "com.google.ipc.invalidation.gcmmplex.";
+ final String bundleRawData = "rawData";
+ final String bundleSenderId = "from";
+ final String bundleSubtype = "subtype";
+
+ if (!extras.containsKey(bundleSubtype)) {
+ throw new IllegalArgumentException("Received push message with no subtype");
+ }
+
+ mSenderId = senderId;
+ mAppId = extras.getString(bundleSubtype);
+
+ mCollapseKey = extras.getString(bundleCollapseKey); // May be null.
+ mRawData = extras.getByteArray(bundleRawData); // May be null.
+
+ List<String> dataKeysAndValues = new ArrayList<String>();
+ for (String key : extras.keySet()) {
+ if (key.equals(bundleSubtype) || key.equals(bundleSenderId)
+ || key.equals(bundleCollapseKey) || key.equals(bundleRawData)
+ || key.startsWith(bundleGcmplex)) {
+ continue;
+ }
+
+ Object value = extras.get(key);
+ if (!(value instanceof String)) {
+ continue;
+ }
+
+ dataKeysAndValues.add(key);
+ dataKeysAndValues.add((String) value);
+ }
+
+ mDataKeysAndValuesArray = dataKeysAndValues.toArray(new String[dataKeysAndValues.size()]);
+ }
+
+ /**
+ * Creates a GCMMessage object based on the given bundle. Assumes that the bundle has previously
+ * been created through {@link #toPersistableBundle}.
+ */
+ @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+ public GCMMessage(PersistableBundle persistableBundle) {
+ mSenderId = persistableBundle.getString(BUNDLE_KEY_SENDER_ID);
+ mAppId = persistableBundle.getString(BUNDLE_KEY_APP_ID);
+ mCollapseKey = persistableBundle.getString(BUNDLE_KEY_COLLAPSE_KEY);
+
+ // The rawData field needs to distinguish between {not set, set but empty, set with data}.
+ String rawDataString = persistableBundle.getString(BUNDLE_KEY_RAW_DATA);
+ if (rawDataString != null) {
+ if (rawDataString.length() > 0) {
+ mRawData = rawDataString.getBytes();
+ } else {
+ mRawData = new byte[0];
+ }
+ }
+
+ mDataKeysAndValuesArray = persistableBundle.getStringArray(BUNDLE_KEY_DATA);
+ }
+
+ public String getSenderId() {
+ return mSenderId;
+ }
+
+ public String getAppId() {
+ return mAppId;
+ }
+
+ @Nullable
+ public String getCollapseKey() {
+ return mCollapseKey;
+ }
+
+ @Nullable
+ public byte[] getRawData() {
+ return mRawData;
Peter Beverloo 2017/02/17 17:33:22 I guess I either make a copy or suppress the warni
awdf 2017/02/18 07:51:41 I guess it's okay since the two places it's called
Peter Beverloo 2017/02/21 14:56:10 Done. https://build.chromium.org/p/tryserver.chro
+ }
+
+ public String[] getDataKeysAndValuesArray() {
+ return mDataKeysAndValuesArray;
Peter Beverloo 2017/02/17 17:33:22 I guess I either make a copy or suppress the warni
Peter Beverloo 2017/02/21 14:56:10 Done.
+ }
+
+ /**
+ * Serializes the contents of this GCM Message to a new persistable bundle that can be stored,
+ * for example for purposes of scheduling a job.
+ */
+ @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+ public PersistableBundle toPersistableBundle() {
+ PersistableBundle persistableBundle = new PersistableBundle();
+ persistableBundle.putString(BUNDLE_KEY_SENDER_ID, mSenderId);
+ persistableBundle.putString(BUNDLE_KEY_APP_ID, mAppId);
+ persistableBundle.putString(BUNDLE_KEY_COLLAPSE_KEY, mCollapseKey);
+
+ // The rawData field needs to distinguish between {not set, set but empty, set with data}.
+ if (mRawData != null) {
+ if (mRawData.length > 0) {
+ persistableBundle.putString(BUNDLE_KEY_RAW_DATA, new String(mRawData));
+ } else {
+ persistableBundle.putString(BUNDLE_KEY_RAW_DATA, new String());
Peter Beverloo 2017/02/17 17:33:22 I mean, I want a non-null empty string. What are t
awdf 2017/02/18 07:51:41 can't you just pass "" ?
Peter Beverloo 2017/02/21 14:56:10 Let's try.
+ }
+ } else {
+ persistableBundle.putString(BUNDLE_KEY_RAW_DATA, null);
+ }
+
+ persistableBundle.putStringArray(BUNDLE_KEY_DATA, mDataKeysAndValuesArray);
+ return persistableBundle;
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698