plugins

October 22, 2022

plugins

CloudControl Provides a mechanism for loading plug-ins, allowing users to write apk with Activity, Service, C/C++ library, etc., install it on an Android device, and load and call it with CloudControl.

A plug-in is an apk file that can be installed independently. After the user installs it, the plug-in is loaded and the API is called through the $plugins module.

$plugins.load(packageName)

  • packageName {string} Loaded plugin package name

Load a plug-in and return the object exported by module.exports in the plug-in module.

If the plug-in is not installed, a PluginLoadException exception will be thrown.

The following is an example of the use of OCR plug-in: (see [OCR plug-in](#ocr plug-in) for the plug-in download address)

How to develop a plugin

The following sample code can be found here for the complete project: Plugin SDKopen in new window

The package names in this example are all org.cloud.plugin.sdk.demo, the plug-in package name may be different in the actual project.

Plug-in SDK integration

Create a new Android project and add in the project's build.gradle file:

allprojects {
    repositories {
        // ...
        maven {url'https://jitpack.io'}
    }
}

Add in the build.gradle file of the specific module (such as app):

dependencies {
    // ...
    implementation'com.github.CloudControlPro:sdk:1.0.0'
}

For more information, see Jitpack.ioopen in new window.

Plug-in configuration

1. Create a new PluginHelloWorld file, inherited from Plugin.

public class PluginHelloWorld extends Plugin {

    public PluginHelloWorld(Context context, Context selfContext, Object runtime, Object topLevelScope) {
        super(context, selfContext, runtime, topLevelScope);
    }

    // Return the assets directory path of the JavaScript glue layer code of the plugin
    @Override
    public String getAssetsScriptDir() {
        return "js-plugin";
    }

    // Plug-in public API, which can be called by JavaScript code
    public String getStringFromJava() {
        return "Hello, CloudControl!";
    }

    // Plug-in public API, which can be called by JavaScript code
    public void say(String message) {
        getSelfContext().startActivity(new Intent(getSelfContext(), HelloWorldActivity.class)
                .putExtra("message", message)
                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
    }
}

2. Added MyPluginRegistry file, inherited from PluginRegistry:

public class MyPluginRegistry extends PluginRegistry {

    static {
        // Register the default plugin
        registerDefaultPlugin(new PluginLoader() {
            @Override
            public Plugin load(Context context, Context selfContext, Object runtime, Object topLevelScope) {
                return new PluginHelloWorld(context, selfContext, runtime, topLevelScope);
            }
        });
    }
}

Configure the following meta-data in AndroidManifest.xml, name is "org.cloud.plugin.sdk.registry", and value is the package name of MyPluginRegistry.

  <application
        ...>

        <meta-data
            android:name="org.cloud.plugin.sdk.registry"
            android:value="org.cloud.plugin.sdk.demo.MyPluginRegistry" />

        <activity
            android:name=".HelloWorldActivity"
            android:exported="true" />

        <service
            android:name=".HelloworldPluginService"
            android:exported="true" />
    </application>

3. Write JavaScript glue layer

Add the index.js file in the corresponding directory of assets (returned by Plugin.getAssetsScriptDir), which is used as a glue layer to export the plugin API.

module.exports = function (plugin) {
    let runtime = plugin.runtime;
    let scope = plugin.topLevelScope;

    function helloWorld() {
    }

    helloWorld.stringFromJava = plugin.getStringFromJava();

    helloWorld.say = function (message) {
        plugin.say(message);
    }

    return helloWorld;
}

4. Call in CloudControl Pro

Compile the plug-in as apk (assembleDebug/assembleRelease) and install it on the device. Use the following code call in CloudControl Pro:

let helloWorld = $plugins.load("org.cloud.plugin.sdk.demo");
console.log(helloWorld.stringFromJava);
helloWorld.say("Hello, CloudControl Pro Plugin");

5. Independent service AIDL method call

You can write a Service in the plug-in, which is invoked and bound by CloudControl Pro, and the Service interface can be called through aidl in js.

Override the method getService in Plugin.

// Plug-in service class, optional, used to communicate with CloudControl Pro ontology in AIDL mode. Can return null
@Override
public ComponentName getService() {
    return new ComponentName(getSelfContext().getPackageName(), HelloworldPluginService.class.getName());
}

Create a new Service component (Note that it needs to be exported="true" when registering in AndroidManifest, inherited from PluginService.

public class HelloworldPluginService extends PluginService {
    private static final String ACTION_ADD = "add";

    @Override
    protected Result onRemoteCall(@NonNull String action, @NonNull Map<String, Object> args, @Nullable RemoteCallback callback) throws RuntimeException {
        switch (action) {
            case ACTION_ADD:
                return invokeAdd(args);
        }
        return Result.notImplemented(action);
    }

    private Result invokeAdd(Map<String, Object> args) {
        Number a = PluginUtils.getNotNull(args, "a");
        Number b = PluginUtils.getNotNull(args, "b");
        double sum = a.doubleValue() + b.doubleValue();
        return new Result(Collections.singletonMap("sum", sum));
    }
}

Add glue layer code in index.js:

helloWorld.remoteAdd = function (a, b) {
    return plugin.waitForConnection().call('add', {
        a: a,
        b: b
    }, null).get('sum');
}

Then you can call in CloudControl Pro:

let helloWorld = $plugins.load("org.cloud.plugin.sdk.demo");
console.log(helloWorld.remoteAdd(1, 2));
Last update:
Contributors: Bruce