提交 93a9d52c 编写于 作者: M Matt Perry

Merge pull request #2182 from flutter/gcm

First steps toward GCM support
# Copyright 2015 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.
# TODO(mpcomplete): move this to a separate repo. Doesn't belong in the main
# Flutter repo.
import("//mojo/public/tools/bindings/mojom.gni")
group("gcm") {
deps = [
":interfaces",
]
if (is_android) {
deps += [ ":gcm_lib" ]
}
}
mojom("interfaces") {
sources = [
"gcm.mojom",
]
}
if (is_android) {
import("//build/config/android/config.gni")
import("//build/config/android/rules.gni")
android_library("gcm_lib") {
java_files = [
"src/org/domokit/gcm/GcmListenerService.java",
"src/org/domokit/gcm/InstanceIDListenerService.java",
"src/org/domokit/gcm/RegistrationIntentService.java",
]
deps = [
"//base:base_java",
"//mojo/java",
"//mojo/public/java:bindings",
"//mojo/public/java:system",
":interfaces_java",
google_play_services_library,
]
}
}
// Copyright 2015 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.
[DartPackage="sky_services"]
module gcm;
[ServiceName="gcm::GcmListener"]
interface GcmListener {
OnMessageReceived(string from, string jsonMessage);
};
[ServiceName="gcm::GcmService"]
interface GcmService {
// senderId is the project_number from google-services.json.
// token should be saved and remembered - you only need to register your app
// once. I don't understand how this token is used, though.
Register(string senderId, GcmListener listener) => (string token);
SubscribeTopics(string token, array<string> topics);
UnsubscribeTopics(string token, array<string> topics);
};
// Copyright 2015 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.domokit.gcm;
import android.os.Bundle;
import android.util.Log;
import java.util.Set;
import org.json.JSONObject;
import org.json.JSONException;
public class GcmListenerService extends com.google.android.gms.gcm.GcmListenerService {
private static final String TAG = "GcmListenerService";
@Override
public void onMessageReceived(String from, Bundle data) {
// Convert the data Bundle to JSON.
JSONObject json = new JSONObject();
Set<String> keys = data.keySet();
for (String key : keys) {
try {
json.put(key, JSONObject.wrap(data.get(key)));
} catch(JSONException e) {
Log.d(TAG, "Failed to convert GCM message to JSON: " + e);
}
}
RegistrationIntentService.notifyMessageReceived(from, json.toString());
}
}
// Copyright 2015 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.domokit.gcm;
import android.content.Intent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.Log;
import com.google.android.gms.iid.InstanceID;
public class InstanceIDListenerService extends com.google.android.gms.iid.InstanceIDListenerService {
/**
* Called if InstanceID token is updated. This may occur if the security of
* the previous token had been compromised. This call is initiated by the
* InstanceID provider.
*/
@Override
public void onTokenRefresh() {
// TODO(mpcomplete): need to notify Dart app?
// Fetch updated Instance ID token and notify our app's server of any changes (if applicable).
Intent intent = new Intent(this, RegistrationIntentService.class);
startService(intent);
}
}
// Copyright 2015 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.domokit.gcm;
import android.app.IntentService;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import com.google.android.gms.gcm.GcmPubSub;
import com.google.android.gms.gcm.GoogleCloudMessaging;
import com.google.android.gms.iid.InstanceID;
import java.io.IOException;
import org.chromium.base.ThreadUtils;
import org.chromium.mojo.system.MojoException;
import org.chromium.mojom.gcm.GcmListener;
import org.chromium.mojom.gcm.GcmService;
public class RegistrationIntentService extends IntentService {
private static final String TAG = "RegistrationIntentService";
private static final String REGISTER_EXTRA = "register";
private static final String TOKEN_EXTRA = "token";
private static final String SUBSCRIBE_EXTRA = "subscribe";
private static final String UNSUBSCRIBE_EXTRA = "unsubscribe";
private static GcmListener sListener;
private static GcmService.RegisterResponse sRegisterResponse;
public static class MojoService implements GcmService {
private Context context;
public MojoService(Context context) {
this.context = context;
}
@Override
public void close() {}
@Override
public void onConnectionError(MojoException e) {}
@Override
public void register(String senderId, GcmListener listener, RegisterResponse response) {
if (checkPlayServices()) {
// Start IntentService to register this application with GCM.
RegistrationIntentService.sListener = listener;
RegistrationIntentService.sRegisterResponse = response;
Intent intent = new Intent(context, RegistrationIntentService.class);
intent.putExtra(REGISTER_EXTRA, senderId);
context.startService(intent);
}
}
public void subscribeTopics(String token, String[] topics) {
Intent intent = new Intent(context, RegistrationIntentService.class);
intent.putExtra(TOKEN_EXTRA, token);
intent.putExtra(SUBSCRIBE_EXTRA, topics);
context.startService(intent);
}
public void unsubscribeTopics(String token, String[] topics) {
Intent intent = new Intent(context, RegistrationIntentService.class);
intent.putExtra(TOKEN_EXTRA, token);
intent.putExtra(UNSUBSCRIBE_EXTRA, topics);
context.startService(intent);
}
private boolean checkPlayServices() {
// TODO(mpcomplete): implement? This would check if the user has the Google Play Services
// library installed, and if not, prompt them to download it.
return true;
}
}
public RegistrationIntentService() {
super(TAG);
}
public static void notifyMessageReceived(final String from, final String message) {
ThreadUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
if (sListener != null)
sListener.onMessageReceived(from, message);
}
});
}
public static void notifyRegistered(final String token) {
ThreadUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
if (sRegisterResponse != null)
sRegisterResponse.call(token);
}
});
}
@Override
protected void onHandleIntent(Intent intent) {
try {
if (intent.hasExtra(REGISTER_EXTRA)) {
register(intent.getStringExtra(REGISTER_EXTRA));
} else if (intent.hasExtra(SUBSCRIBE_EXTRA)) {
subscribeTopics(
intent.getStringExtra(TOKEN_EXTRA),
intent.getStringArrayExtra(SUBSCRIBE_EXTRA));
} else if (intent.hasExtra(UNSUBSCRIBE_EXTRA)) {
unsubscribeTopics(
intent.getStringExtra(TOKEN_EXTRA),
intent.getStringArrayExtra(UNSUBSCRIBE_EXTRA));
} else {
Log.d(TAG, "Unexpected intent.");
}
} catch (Exception e) {
Log.d(TAG, "Failed to process GCM request", e);
}
}
private void register(String senderId) {
try {
InstanceID instanceID = InstanceID.getInstance(this);
String token = instanceID.getToken(senderId,
GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
notifyRegistered(token);
} catch (Exception e) {
Log.d(TAG, "Failed to complete token refresh", e);
// TODO(mpcomplete): callback error code.
}
}
private void subscribeTopics(String token, String[] topics) throws IOException {
GcmPubSub pubSub = GcmPubSub.getInstance(this);
for (String topic : topics) {
pubSub.subscribe(token, "/topics/" + topic, null);
}
}
private void unsubscribeTopics(String token, String[] topics) throws IOException {
GcmPubSub pubSub = GcmPubSub.getInstance(this);
for (String topic : topics) {
pubSub.unsubscribe(token, "/topics/" + topic);
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册