org.chromium.BackgroundPlugin.java Source code

Java tutorial

Introduction

Here is the source code for org.chromium.BackgroundPlugin.java

Source

// Copyright (c) 2013 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;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaArgs;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.PluginResult;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.util.Log;

public class BackgroundPlugin extends CordovaPlugin {
    private static final String LOG_TAG = "BackgroundPlugin";

    // This reference lets us know whether or not the app is currently running.
    static BackgroundPlugin pluginInstance;
    private CallbackContext messageChannel;
    private boolean isMainInstance;
    private boolean resumeEventSeen;

    @Override
    public void pluginInitialize() {
        isMainInstance = pluginInstance == null;
        if (isMainInstance) {
            pluginInstance = this;
        }
    }

    @Override
    public void onReset() {
        messageChannel = null;
        if (isMainInstance) {
            releasePluginMessageChannels();
        }
    }

    @Override
    public void onResume(boolean multitasking) {
        // Ignore the resume on start-up, but assume messageChannel means there was no onResume on start-up.
        // Cordova has flip-flopped on whether to send this event on start-up :S.
        if (!resumeEventSeen && messageChannel == null) {
            resumeEventSeen = true;
            return;
        }
        if (isMainInstance && BackgroundActivity.topInstance != null) {
            final BackgroundActivity topInstance = BackgroundActivity.topInstance;
            BackgroundActivity.topInstance = null;
            // Kill off the BackgroundActivity task stack. Leaving it around causes the next call
            // to BackgroundActivity.launchBackground() to have MainActivity in the wrong task stack.
            webView.getView().postDelayed(new Runnable() {
                @Override
                public void run() {
                    Log.i(LOG_TAG, "Finishing background activity now that foreground is alive");
                    topInstance.finish();
                }
            }, 50);
        }
        String switchType = BackgroundActivity.prevLaunchWasProgrammatic ? "programmatic" : "normal";
        sendEventMessage("foreground", switchType);

        if (isMainInstance) {
            webView.getView().post(new Runnable() {
                @Override
                public void run() {
                    BackgroundActivity.prevLaunchWasProgrammatic = false;
                }
            });
        }
    }

    @Override
    public void onDestroy() {
        messageChannel = null;
        if (isMainInstance) {
            pluginInstance = null;
            releasePluginMessageChannels();
        }
    }

    @Override
    public boolean execute(String action, CordovaArgs args, final CallbackContext callbackContext)
            throws JSONException {
        if ("messageChannel".equals(action)) {
            messageChannel = callbackContext;
            sendEventMessage("startup", BackgroundActivity.topInstance != null);
            return true;
        } else if ("show".equals(action)) {
            cordova.getThreadPool().execute(new Runnable() {
                @Override
                public void run() {
                    show(callbackContext);
                }
            });
            return true;
        }
        return false;
    }

    private void sendEventMessage(String action, Object value) {
        if (messageChannel == null) {
            Log.w(LOG_TAG, "Message being dropped since channel not yet established: " + action);
            return;
        }
        JSONObject obj = new JSONObject();
        try {
            obj.put("type", action);
            obj.put("value", value);
        } catch (JSONException e) {
            Log.e(LOG_TAG, "Failed to create background event", e);
        }
        PluginResult pluginResult = new PluginResult(PluginResult.Status.OK, obj);
        pluginResult.setKeepCallback(true);
        messageChannel.sendPluginResult(pluginResult);
    }

    private void show(final CallbackContext callbackContext) {
        Activity activity = cordova.getActivity();

        if (!activity.hasWindowFocus()) {
            BackgroundActivity.launchForeground(activity, false);
        }
        callbackContext.success();
    }

    private static void releasePluginMessageChannels() {
        // Release the message channel for all plugins using our background event handler
        //  - The Cordova Plugin framework does not provide a direct way to handle the life cycle
        //    events for plugins (e.g. onReset, onDestroy)
        //  - To avoid extra boilerplate in any plugin using the event handler, will cleanup all
        //    the message channels for plugins here
        BackgroundEventHandler.releaseMessageChannels();
    }
}