forked from flutter/engine
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request flutter#2182 from flutter/gcm
First steps toward GCM support
- Loading branch information
Showing
5 changed files
with
275 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
# 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, | ||
] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// 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); | ||
}; |
32 changes: 32 additions & 0 deletions
32
sky/services/gcm/src/org/domokit/gcm/GcmListenerService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// 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()); | ||
} | ||
} |
27 changes: 27 additions & 0 deletions
27
sky/services/gcm/src/org/domokit/gcm/InstanceIDListenerService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
// 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); | ||
} | ||
} |
149 changes: 149 additions & 0 deletions
149
sky/services/gcm/src/org/domokit/gcm/RegistrationIntentService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
// 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); | ||
} | ||
} | ||
} |