Skip to content

Commit

Permalink
Support dynamic registration of mojo services on Android
Browse files Browse the repository at this point in the history
SkyApplication now reads service info from a services.json file bundled
with the apk. For each service, it registers a method that invokes
connectToService on a named class. This way, third party services can
register themselves.

There's a corresponding change to flutter_tools to generate this
services.json when building an apk that depends on services.
  • Loading branch information
mpcomplete committed Jan 21, 2016
1 parent 8b4d246 commit 0ee5a29
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 3 deletions.
14 changes: 12 additions & 2 deletions build/config/android/rules.gni
Original file line number Diff line number Diff line change
Expand Up @@ -1577,7 +1577,7 @@ template("android_apk") {
}

final_deps += [ ":$final_dex_target_name" ]
dex("$final_dex_target_name") {
dex("${final_dex_target_name}_jar") {
deps = [
":$build_config_target",
":$java_target",
Expand All @@ -1588,11 +1588,21 @@ template("android_apk") {
inputs = [
_build_config,
]
output = final_dex_path
output = "${final_dex_path}.jar"
dex_arg_key = "${_rebased_build_config}:final_dex:dependency_dex_files"
args = [ "--inputs=@FileArg($dex_arg_key)" ]
}

dex("$final_dex_target_name") {
deps = [
":${final_dex_target_name}_jar",
]
sources = [
"${final_dex_path}.jar",
]
output = final_dex_path
}

if (_native_libs != []) {
action("${_template_name}__prepare_native") {
script = "//build/android/gyp/pack_relocations.py"
Expand Down
8 changes: 8 additions & 0 deletions sky/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,17 @@ group("sky") {

if (is_android) {
deps += [ "//sky/services/activity" ]

# TODO(mpcomplete): This is temporary until we move GCM out of the engine
# repo.
deps += [
"//sky/services/gcm:gcm_lib",
"//sky/services/gcm:interfaces_java",
]
}

if (!is_android) {
deps += [ "//third_party/mesa:osmesa" ]
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
import java.io.IOException;

import org.chromium.base.ThreadUtils;
import org.chromium.mojo.system.Core;
import org.chromium.mojo.system.MessagePipeHandle;
import org.chromium.mojo.system.MojoException;
import org.chromium.mojom.gcm.GcmListener;
import org.chromium.mojom.gcm.GcmService;
Expand All @@ -37,6 +39,10 @@ public MojoService(Context context) {
this.context = context;
}

public static void connectToService(Context context, Core core, MessagePipeHandle pipe) {
GcmService.MANAGER.bind(new MojoService(context), pipe);
}

@Override
public void close() {}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,15 @@
package org.domokit.sky.shell;

import android.content.Context;
import android.content.res.AssetManager;
import android.util.Log;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.InputStreamReader;
import java.io.IOException;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONTokener;

import org.chromium.base.BaseChromiumApplication;
import org.chromium.base.library_loader.LibraryLoader;
Expand Down Expand Up @@ -35,6 +43,7 @@
public class SkyApplication extends BaseChromiumApplication {
static final String APP_BUNDLE = "app.flx";
static final String MANIFEST = "flutter.yaml";
static final String SERVICES = "services.json";

private static final String TAG = "SkyApplication";
private static final String PRIVATE_DATA_DIRECTORY_SUFFIX = "sky_shell";
Expand Down Expand Up @@ -67,6 +76,8 @@ protected void onBeforeResourceExtraction(ResourceExtractor extractor) {
* Override this function to register more services.
*/
protected void onServiceRegistryAvailable(ServiceRegistry registry) {
parseServicesConfig(registry);

registry.register(Activity.MANAGER.getName(), new ServiceFactory() {
@Override
public void connectToService(Context context, Core core, MessagePipeHandle pipe) {
Expand Down Expand Up @@ -119,6 +130,55 @@ public void connectToService(Context context, Core core, MessagePipeHandle pipe)
});
}

/**
* Parses the auto-generated services.json file, which contains additional services to register.
*/
private void parseServicesConfig(ServiceRegistry registry) {
final AssetManager manager = getResources().getAssets();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(manager.open(SERVICES)))) {
StringBuffer json = new StringBuffer();
while (true) {
String line = reader.readLine();
if (line == null)
break;
json.append(line);
}

JSONObject object = (JSONObject) new JSONTokener(json.toString()).nextValue();
JSONArray services = object.getJSONArray("services");
for (int i = 0; i < services.length(); ++i) {
JSONObject service = services.getJSONObject(i);
String serviceName = service.getString("name");
String className = service.getString("class");
registerService(registry, serviceName, className);
}
} catch (FileNotFoundException e) {
// Not all apps will have a services.json file.
return;
} catch (Exception e) {
Log.e(TAG, "Failure parsing service configuration file", e);
return;
}
}

/**
* Registers a third-party service.
*/
private void registerService(ServiceRegistry registry, final String serviceName, final String className) {
registry.register(serviceName, new ServiceFactory() {
@Override
public void connectToService(Context context, Core core, MessagePipeHandle pipe) {
try {
Class.forName(className)
.getMethod("connectToService", Context.class, Core.class, MessagePipeHandle.class)
.invoke(null, context, core, pipe);
} catch(Exception e) {
Log.e(TAG, "Failed to register service '" + serviceName + "'", e);
}
}
});
}

private void initJavaUtils() {
PathUtils.setPrivateDataDirectorySuffix(PRIVATE_DATA_DIRECTORY_SUFFIX,
getApplicationContext());
Expand Down
4 changes: 3 additions & 1 deletion sky/tools/release_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,10 @@ def git_revision(cwd):
'icudtl.dat',
'dist/shell/SkyShell.apk',
'dist/shell/flutter.mojo',
'gen/sky/shell/shell/classes.dex',
'gen/sky/shell/shell/classes.dex.jar',
'gen/sky/shell/shell/shell/libs/armeabi-v7a/libsky_shell.so',
# TODO(mpcomplete): obsolete. Remove after updating the flutter tool.
'gen/sky/shell/shell/classes.dex',
],
'linux-x64': [
'dist/shell/icudtl.dat',
Expand Down

0 comments on commit 0ee5a29

Please sign in to comment.