1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/mobile/android/base/OrderedBroadcastHelper.java Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,129 @@ 1.4 +/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- 1.5 + * This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +package org.mozilla.gecko; 1.10 + 1.11 +import org.mozilla.gecko.background.common.GlobalConstants; 1.12 +import org.mozilla.gecko.EventDispatcher; 1.13 +import org.mozilla.gecko.util.GeckoEventListener; 1.14 + 1.15 +import org.json.JSONException; 1.16 +import org.json.JSONObject; 1.17 + 1.18 +import android.app.Activity; 1.19 + 1.20 +import android.content.BroadcastReceiver; 1.21 +import android.content.Context; 1.22 +import android.content.Intent; 1.23 + 1.24 +import android.util.Log; 1.25 + 1.26 +/** 1.27 + * Helper class to send Android Ordered Broadcasts. 1.28 + */ 1.29 +public final class OrderedBroadcastHelper 1.30 + implements GeckoEventListener 1.31 +{ 1.32 + public static final String LOGTAG = "GeckoOrdBroadcast"; 1.33 + 1.34 + public static final String SEND_EVENT = "OrderedBroadcast:Send"; 1.35 + 1.36 + protected final Context mContext; 1.37 + 1.38 + public OrderedBroadcastHelper(Context context) { 1.39 + mContext = context; 1.40 + 1.41 + EventDispatcher dispatcher = GeckoAppShell.getEventDispatcher(); 1.42 + if (dispatcher == null) { 1.43 + Log.e(LOGTAG, "Gecko event dispatcher must not be null", new RuntimeException()); 1.44 + return; 1.45 + } 1.46 + dispatcher.registerEventListener(SEND_EVENT, this); 1.47 + } 1.48 + 1.49 + public synchronized void uninit() { 1.50 + EventDispatcher dispatcher = GeckoAppShell.getEventDispatcher(); 1.51 + if (dispatcher == null) { 1.52 + Log.e(LOGTAG, "Gecko event dispatcher must not be null", new RuntimeException()); 1.53 + return; 1.54 + } 1.55 + dispatcher.unregisterEventListener(SEND_EVENT, this); 1.56 + } 1.57 + 1.58 + @Override 1.59 + public void handleMessage(String event, JSONObject message) { 1.60 + if (!SEND_EVENT.equals(event)) { 1.61 + Log.e(LOGTAG, "OrderedBroadcastHelper got unexpected message " + event); 1.62 + return; 1.63 + } 1.64 + 1.65 + try { 1.66 + final String action = message.getString("action"); 1.67 + if (action == null) { 1.68 + Log.e(LOGTAG, "action must not be null"); 1.69 + return; 1.70 + } 1.71 + 1.72 + final String responseEvent = message.getString("responseEvent"); 1.73 + if (responseEvent == null) { 1.74 + Log.e(LOGTAG, "responseEvent must not be null"); 1.75 + return; 1.76 + } 1.77 + 1.78 + // It's fine if the caller-provided token is missing or null. 1.79 + final JSONObject token = (message.has("token") && !message.isNull("token")) ? 1.80 + message.getJSONObject("token") : null; 1.81 + 1.82 + // A missing (undefined) permission means the intent will be limited 1.83 + // to the current package. A null means no permission, so any 1.84 + // package can receive the intent. 1.85 + final String permission = message.has("permission") ? 1.86 + (message.isNull("permission") ? null : message.getString("permission")) : 1.87 + GlobalConstants.PER_ANDROID_PACKAGE_PERMISSION; 1.88 + 1.89 + final BroadcastReceiver resultReceiver = new BroadcastReceiver() { 1.90 + @Override 1.91 + public void onReceive(Context context, Intent intent) { 1.92 + int code = getResultCode(); 1.93 + 1.94 + if (code == Activity.RESULT_OK) { 1.95 + String data = getResultData(); 1.96 + 1.97 + JSONObject res = new JSONObject(); 1.98 + try { 1.99 + res.put("action", action); 1.100 + res.put("token", token); 1.101 + res.put("data", data); 1.102 + } catch (JSONException e) { 1.103 + Log.e(LOGTAG, "Got exception in onReceive handling action " + action, e); 1.104 + return; 1.105 + } 1.106 + 1.107 + GeckoEvent event = GeckoEvent.createBroadcastEvent(responseEvent, res.toString()); 1.108 + GeckoAppShell.sendEventToGecko(event); 1.109 + } 1.110 + } 1.111 + }; 1.112 + 1.113 + Intent intent = new Intent(action); 1.114 + // OrderedBroadcast.jsm adds its callback ID to the caller's token; 1.115 + // this unwraps that wrapping. 1.116 + if (token != null && token.has("data")) { 1.117 + intent.putExtra("token", token.getString("data")); 1.118 + } 1.119 + 1.120 + mContext.sendOrderedBroadcast(intent, 1.121 + permission, 1.122 + resultReceiver, 1.123 + null, 1.124 + Activity.RESULT_OK, 1.125 + null, 1.126 + null); 1.127 + } catch (JSONException e) { 1.128 + Log.e(LOGTAG, "Got exception in handleMessage handling event " + event, e); 1.129 + return; 1.130 + } 1.131 + } 1.132 +}