michael@0: /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: package org.mozilla.gecko; michael@0: michael@0: import org.mozilla.gecko.background.common.GlobalConstants; michael@0: import org.mozilla.gecko.EventDispatcher; michael@0: import org.mozilla.gecko.util.GeckoEventListener; michael@0: michael@0: import org.json.JSONException; michael@0: import org.json.JSONObject; michael@0: michael@0: import android.app.Activity; michael@0: michael@0: import android.content.BroadcastReceiver; michael@0: import android.content.Context; michael@0: import android.content.Intent; michael@0: michael@0: import android.util.Log; michael@0: michael@0: /** michael@0: * Helper class to send Android Ordered Broadcasts. michael@0: */ michael@0: public final class OrderedBroadcastHelper michael@0: implements GeckoEventListener michael@0: { michael@0: public static final String LOGTAG = "GeckoOrdBroadcast"; michael@0: michael@0: public static final String SEND_EVENT = "OrderedBroadcast:Send"; michael@0: michael@0: protected final Context mContext; michael@0: michael@0: public OrderedBroadcastHelper(Context context) { michael@0: mContext = context; michael@0: michael@0: EventDispatcher dispatcher = GeckoAppShell.getEventDispatcher(); michael@0: if (dispatcher == null) { michael@0: Log.e(LOGTAG, "Gecko event dispatcher must not be null", new RuntimeException()); michael@0: return; michael@0: } michael@0: dispatcher.registerEventListener(SEND_EVENT, this); michael@0: } michael@0: michael@0: public synchronized void uninit() { michael@0: EventDispatcher dispatcher = GeckoAppShell.getEventDispatcher(); michael@0: if (dispatcher == null) { michael@0: Log.e(LOGTAG, "Gecko event dispatcher must not be null", new RuntimeException()); michael@0: return; michael@0: } michael@0: dispatcher.unregisterEventListener(SEND_EVENT, this); michael@0: } michael@0: michael@0: @Override michael@0: public void handleMessage(String event, JSONObject message) { michael@0: if (!SEND_EVENT.equals(event)) { michael@0: Log.e(LOGTAG, "OrderedBroadcastHelper got unexpected message " + event); michael@0: return; michael@0: } michael@0: michael@0: try { michael@0: final String action = message.getString("action"); michael@0: if (action == null) { michael@0: Log.e(LOGTAG, "action must not be null"); michael@0: return; michael@0: } michael@0: michael@0: final String responseEvent = message.getString("responseEvent"); michael@0: if (responseEvent == null) { michael@0: Log.e(LOGTAG, "responseEvent must not be null"); michael@0: return; michael@0: } michael@0: michael@0: // It's fine if the caller-provided token is missing or null. michael@0: final JSONObject token = (message.has("token") && !message.isNull("token")) ? michael@0: message.getJSONObject("token") : null; michael@0: michael@0: // A missing (undefined) permission means the intent will be limited michael@0: // to the current package. A null means no permission, so any michael@0: // package can receive the intent. michael@0: final String permission = message.has("permission") ? michael@0: (message.isNull("permission") ? null : message.getString("permission")) : michael@0: GlobalConstants.PER_ANDROID_PACKAGE_PERMISSION; michael@0: michael@0: final BroadcastReceiver resultReceiver = new BroadcastReceiver() { michael@0: @Override michael@0: public void onReceive(Context context, Intent intent) { michael@0: int code = getResultCode(); michael@0: michael@0: if (code == Activity.RESULT_OK) { michael@0: String data = getResultData(); michael@0: michael@0: JSONObject res = new JSONObject(); michael@0: try { michael@0: res.put("action", action); michael@0: res.put("token", token); michael@0: res.put("data", data); michael@0: } catch (JSONException e) { michael@0: Log.e(LOGTAG, "Got exception in onReceive handling action " + action, e); michael@0: return; michael@0: } michael@0: michael@0: GeckoEvent event = GeckoEvent.createBroadcastEvent(responseEvent, res.toString()); michael@0: GeckoAppShell.sendEventToGecko(event); michael@0: } michael@0: } michael@0: }; michael@0: michael@0: Intent intent = new Intent(action); michael@0: // OrderedBroadcast.jsm adds its callback ID to the caller's token; michael@0: // this unwraps that wrapping. michael@0: if (token != null && token.has("data")) { michael@0: intent.putExtra("token", token.getString("data")); michael@0: } michael@0: michael@0: mContext.sendOrderedBroadcast(intent, michael@0: permission, michael@0: resultReceiver, michael@0: null, michael@0: Activity.RESULT_OK, michael@0: null, michael@0: null); michael@0: } catch (JSONException e) { michael@0: Log.e(LOGTAG, "Got exception in handleMessage handling event " + event, e); michael@0: return; michael@0: } michael@0: } michael@0: }