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.util.GeckoEventListener; michael@0: michael@0: import org.json.JSONArray; michael@0: import org.json.JSONException; michael@0: import org.json.JSONObject; michael@0: michael@0: import android.util.Log; michael@0: import android.util.SparseArray; michael@0: michael@0: import java.util.ArrayList; michael@0: michael@0: /** michael@0: * Helper class to get/set gecko prefs. michael@0: */ michael@0: public final class PrefsHelper { michael@0: private static final String LOGTAG = "GeckoPrefsHelper"; michael@0: michael@0: private static boolean sRegistered = false; michael@0: private static final SparseArray sCallbacks = new SparseArray(); michael@0: private static int sUniqueRequestId = 1; michael@0: michael@0: public static int getPref(String prefName, PrefHandler callback) { michael@0: return getPrefsInternal(new String[] { prefName }, callback); michael@0: } michael@0: michael@0: public static int getPrefs(String[] prefNames, PrefHandler callback) { michael@0: return getPrefsInternal(prefNames, callback); michael@0: } michael@0: michael@0: public static int getPrefs(ArrayList prefNames, PrefHandler callback) { michael@0: return getPrefsInternal(prefNames.toArray(new String[prefNames.size()]), callback); michael@0: } michael@0: michael@0: private static int getPrefsInternal(String[] prefNames, PrefHandler callback) { michael@0: int requestId; michael@0: synchronized (PrefsHelper.class) { michael@0: ensureRegistered(); michael@0: michael@0: requestId = sUniqueRequestId++; michael@0: sCallbacks.put(requestId, callback); michael@0: } michael@0: michael@0: GeckoEvent event; michael@0: if (callback.isObserver()) { michael@0: event = GeckoEvent.createPreferencesObserveEvent(requestId, prefNames); michael@0: } else { michael@0: event = GeckoEvent.createPreferencesGetEvent(requestId, prefNames); michael@0: } michael@0: GeckoAppShell.sendEventToGecko(event); michael@0: michael@0: return requestId; michael@0: } michael@0: michael@0: private static void ensureRegistered() { michael@0: if (sRegistered) { michael@0: return; michael@0: } michael@0: michael@0: GeckoAppShell.getEventDispatcher().registerEventListener("Preferences:Data", new GeckoEventListener() { michael@0: @Override public void handleMessage(String event, JSONObject message) { michael@0: try { michael@0: PrefHandler callback; michael@0: synchronized (PrefsHelper.class) { michael@0: try { michael@0: int requestId = message.getInt("requestId"); michael@0: callback = sCallbacks.get(requestId); michael@0: if (callback != null && !callback.isObserver()) { michael@0: sCallbacks.delete(requestId); michael@0: } michael@0: } catch (Exception e) { michael@0: callback = null; michael@0: } michael@0: } michael@0: if (callback == null) { michael@0: Log.d(LOGTAG, "Preferences:Data message had an unknown requestId; ignoring"); michael@0: return; michael@0: } michael@0: michael@0: JSONArray jsonPrefs = message.getJSONArray("preferences"); michael@0: for (int i = 0; i < jsonPrefs.length(); i++) { michael@0: JSONObject pref = jsonPrefs.getJSONObject(i); michael@0: String name = pref.getString("name"); michael@0: String type = pref.getString("type"); michael@0: try { michael@0: if ("bool".equals(type)) { michael@0: callback.prefValue(name, pref.getBoolean("value")); michael@0: } else if ("int".equals(type)) { michael@0: callback.prefValue(name, pref.getInt("value")); michael@0: } else if ("string".equals(type)) { michael@0: callback.prefValue(name, pref.getString("value")); michael@0: } else { michael@0: Log.e(LOGTAG, "Unknown pref value type [" + type + "] for pref [" + name + "]"); michael@0: } michael@0: } catch (Exception e) { michael@0: Log.e(LOGTAG, "Handler for preference [" + name + "] threw exception", e); michael@0: } michael@0: } michael@0: callback.finish(); michael@0: } catch (Exception e) { michael@0: Log.e(LOGTAG, "Error handling Preferences:Data message", e); michael@0: } michael@0: } michael@0: }); michael@0: sRegistered = true; michael@0: } michael@0: michael@0: public static void setPref(String pref, Object value) { michael@0: if (pref == null || pref.length() == 0) { michael@0: throw new IllegalArgumentException("Pref name must be non-empty"); michael@0: } michael@0: michael@0: try { michael@0: JSONObject jsonPref = new JSONObject(); michael@0: jsonPref.put("name", pref); michael@0: if (value instanceof Boolean) { michael@0: jsonPref.put("type", "bool"); michael@0: jsonPref.put("value", ((Boolean)value).booleanValue()); michael@0: } else if (value instanceof Integer) { michael@0: jsonPref.put("type", "int"); michael@0: jsonPref.put("value", ((Integer)value).intValue()); michael@0: } else { michael@0: jsonPref.put("type", "string"); michael@0: jsonPref.put("value", String.valueOf(value)); michael@0: } michael@0: michael@0: GeckoEvent event = GeckoEvent.createBroadcastEvent("Preferences:Set", jsonPref.toString()); michael@0: GeckoAppShell.sendEventToGecko(event); michael@0: } catch (JSONException e) { michael@0: Log.e(LOGTAG, "Error setting pref [" + pref + "]", e); michael@0: } michael@0: } michael@0: michael@0: public static void removeObserver(int requestId) { michael@0: if (requestId < 0) { michael@0: throw new IllegalArgumentException("Invalid request ID"); michael@0: } michael@0: michael@0: synchronized (PrefsHelper.class) { michael@0: PrefHandler callback = sCallbacks.get(requestId); michael@0: sCallbacks.delete(requestId); michael@0: michael@0: if (callback == null) { michael@0: Log.e(LOGTAG, "Unknown request ID " + requestId); michael@0: return; michael@0: } michael@0: } michael@0: michael@0: GeckoEvent event = GeckoEvent.createBroadcastEvent("Preferences:RemoveObserver", michael@0: Integer.toString(requestId)); michael@0: GeckoAppShell.sendEventToGecko(event); michael@0: } michael@0: michael@0: public interface PrefHandler { michael@0: void prefValue(String pref, boolean value); michael@0: void prefValue(String pref, int value); michael@0: void prefValue(String pref, String value); michael@0: boolean isObserver(); michael@0: void finish(); michael@0: } michael@0: michael@0: public static abstract class PrefHandlerBase implements PrefHandler { michael@0: @Override michael@0: public void prefValue(String pref, boolean value) { michael@0: Log.w(LOGTAG, "Unhandled boolean value for pref [" + pref + "]"); michael@0: } michael@0: michael@0: @Override michael@0: public void prefValue(String pref, int value) { michael@0: Log.w(LOGTAG, "Unhandled int value for pref [" + pref + "]"); michael@0: } michael@0: michael@0: @Override michael@0: public void prefValue(String pref, String value) { michael@0: Log.w(LOGTAG, "Unhandled String value for pref [" + pref + "]"); michael@0: } michael@0: michael@0: @Override michael@0: public void finish() { michael@0: } michael@0: michael@0: @Override michael@0: public boolean isObserver() { michael@0: return false; michael@0: } michael@0: } michael@0: }