mobile/android/base/SharedPreferencesHelper.java

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

     1 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
     2  * This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 package org.mozilla.gecko;
     8 import org.mozilla.gecko.EventDispatcher;
     9 import org.mozilla.gecko.util.GeckoEventListener;
    11 import org.json.JSONArray;
    12 import org.json.JSONException;
    13 import org.json.JSONObject;
    15 import android.content.Context;
    16 import android.content.SharedPreferences;
    17 import android.util.Log;
    19 import java.util.Map;
    20 import java.util.HashMap;
    22 /**
    23  * Helper class to get, set, and observe Android Shared Preferences.
    24  */
    25 public final class SharedPreferencesHelper
    26              implements GeckoEventListener
    27 {
    28     public static final String LOGTAG = "GeckoAndSharedPrefs";
    30     protected final Context mContext;
    32     // mListeners is not synchronized because it is only updated in
    33     // handleObserve, which is called from Gecko serially.
    34     protected final Map<String, SharedPreferences.OnSharedPreferenceChangeListener> mListeners;
    36     public SharedPreferencesHelper(Context context) {
    37         mContext = context;
    39         mListeners = new HashMap<String, SharedPreferences.OnSharedPreferenceChangeListener>();
    41         EventDispatcher dispatcher = GeckoAppShell.getEventDispatcher();
    42         if (dispatcher == null) {
    43             Log.e(LOGTAG, "Gecko event dispatcher must not be null", new RuntimeException());
    44             return;
    45         }
    46         dispatcher.registerEventListener("SharedPreferences:Set", this);
    47         dispatcher.registerEventListener("SharedPreferences:Get", this);
    48         dispatcher.registerEventListener("SharedPreferences:Observe", this);
    49     }
    51     public synchronized void uninit() {
    52         EventDispatcher dispatcher = GeckoAppShell.getEventDispatcher();
    53         if (dispatcher == null) {
    54             Log.e(LOGTAG, "Gecko event dispatcher must not be null", new RuntimeException());
    55             return;
    56         }
    58         dispatcher.unregisterEventListener("SharedPreferences:Set", this);
    59         dispatcher.unregisterEventListener("SharedPreferences:Get", this);
    60         dispatcher.unregisterEventListener("SharedPreferences:Observe", this);
    61     }
    63     private SharedPreferences getSharedPreferences(String branch) {
    64         if (branch == null) {
    65             return GeckoSharedPrefs.forApp(mContext);
    66         } else {
    67             return mContext.getSharedPreferences(branch, Context.MODE_PRIVATE);
    68         }
    69     }
    71     /**
    72      * Set many SharedPreferences in Android.
    73      *
    74      * message.branch must exist, and should be a String SharedPreferences
    75      * branch name, or null for the default branch.
    76      * message.preferences should be an array of preferences.  Each preference
    77      * must include a String name, a String type in ["bool", "int", "string"],
    78      * and an Object value.
    79      */
    80     private void handleSet(JSONObject message) throws JSONException {
    81         if (!message.has("branch")) {
    82             Log.e(LOGTAG, "No branch specified for SharedPreference:Set; aborting.");
    83             return;
    84         }
    86         String branch = message.isNull("branch") ? null : message.getString("branch");
    87         SharedPreferences.Editor editor = getSharedPreferences(branch).edit();
    89         JSONArray jsonPrefs = message.getJSONArray("preferences");
    91         for (int i = 0; i < jsonPrefs.length(); i++) {
    92             JSONObject pref = jsonPrefs.getJSONObject(i);
    93             String name = pref.getString("name");
    94             String type = pref.getString("type");
    95             if ("bool".equals(type)) {
    96                 editor.putBoolean(name, pref.getBoolean("value"));
    97             } else if ("int".equals(type)) {
    98                 editor.putInt(name, pref.getInt("value"));
    99             } else if ("string".equals(type)) {
   100                 editor.putString(name, pref.getString("value"));
   101             } else {
   102                 Log.w(LOGTAG, "Unknown pref value type [" + type + "] for pref [" + name + "]");
   103             }
   104             editor.commit();
   105         }
   106     }
   108     /**
   109      * Get many SharedPreferences from Android.
   110      *
   111      * message.branch must exist, and should be a String SharedPreferences
   112      * branch name, or null for the default branch.
   113      * message.preferences should be an array of preferences.  Each preference
   114      * must include a String name, and a String type in ["bool", "int",
   115      * "string"].
   116      */
   117     private JSONArray handleGet(JSONObject message) throws JSONException {
   118         if (!message.has("branch")) {
   119             Log.e(LOGTAG, "No branch specified for SharedPreference:Get; aborting.");
   120             return null;
   121         }
   123         String branch = message.isNull("branch") ? null : message.getString("branch");
   124         SharedPreferences prefs = getSharedPreferences(branch);
   125         JSONArray jsonPrefs = message.getJSONArray("preferences");
   126         JSONArray jsonValues = new JSONArray();
   128         for (int i = 0; i < jsonPrefs.length(); i++) {
   129             JSONObject pref = jsonPrefs.getJSONObject(i);
   130             String name = pref.getString("name");
   131             String type = pref.getString("type");
   132             JSONObject jsonValue = new JSONObject();
   133             jsonValue.put("name", name);
   134             jsonValue.put("type", type);
   135             try {
   136                 if ("bool".equals(type)) {
   137                     boolean value = prefs.getBoolean(name, false);
   138                     jsonValue.put("value", value);
   139                 } else if ("int".equals(type)) {
   140                     int value = prefs.getInt(name, 0);
   141                     jsonValue.put("value", value);
   142                 } else if ("string".equals(type)) {
   143                     String value = prefs.getString(name, "");
   144                     jsonValue.put("value", value);
   145                 } else {
   146                     Log.w(LOGTAG, "Unknown pref value type [" + type + "] for pref [" + name + "]");
   147                 }
   148             } catch (ClassCastException e) {
   149                 // Thrown if there is a preference with the given name that is
   150                 // not the right type.
   151                 Log.w(LOGTAG, "Wrong pref value type [" + type + "] for pref [" + name + "]");
   152             }
   153             jsonValues.put(jsonValue);
   154         }
   156         return jsonValues;
   157     }
   159     private static class ChangeListener
   160         implements SharedPreferences.OnSharedPreferenceChangeListener {
   161         public final String branch;
   163         public ChangeListener(final String branch) {
   164             this.branch = branch;
   165         }
   167         @Override
   168         public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
   169             if (Log.isLoggable(LOGTAG, Log.VERBOSE)) {
   170                 Log.v(LOGTAG, "Got onSharedPreferenceChanged");
   171             }
   172             try {
   173                 final JSONObject msg = new JSONObject();
   174                 msg.put("branch", this.branch);
   175                 msg.put("key", key);
   177                 // Truly, this is awful, but the API impedence is strong: there
   178                 // is no way to get a single untyped value from a
   179                 // SharedPreferences instance.
   180                 msg.put("value", sharedPreferences.getAll().get(key));
   182                 GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("SharedPreferences:Changed", msg.toString()));
   183             } catch (JSONException e) {
   184                 Log.e(LOGTAG, "Got exception creating JSON object", e);
   185                 return;
   186             }
   187         }
   188     }
   190     /**
   191      * Register or unregister a SharedPreferences.OnSharedPreferenceChangeListener.
   192      *
   193      * message.branch must exist, and should be a String SharedPreferences
   194      * branch name, or null for the default branch.
   195      * message.enable should be a boolean: true to enable listening, false to
   196      * disable listening.
   197      */
   198     private void handleObserve(JSONObject message) throws JSONException {
   199         if (!message.has("branch")) {
   200             Log.e(LOGTAG, "No branch specified for SharedPreference:Observe; aborting.");
   201             return;
   202         }
   204         String branch = message.isNull("branch") ? null : message.getString("branch");
   205         SharedPreferences prefs = getSharedPreferences(branch);
   206         boolean enable = message.getBoolean("enable");
   208         // mListeners is only modified in this one observer, which is called
   209         // from Gecko serially.
   210         if (enable && !this.mListeners.containsKey(branch)) {
   211             SharedPreferences.OnSharedPreferenceChangeListener listener = new ChangeListener(branch);
   212             this.mListeners.put(branch, listener);
   213             prefs.registerOnSharedPreferenceChangeListener(listener);
   214         }
   215         if (!enable && this.mListeners.containsKey(branch)) {
   216             SharedPreferences.OnSharedPreferenceChangeListener listener = this.mListeners.remove(branch);
   217             prefs.unregisterOnSharedPreferenceChangeListener(listener);
   218         }
   219     }
   221     @Override
   222     public void handleMessage(String event, JSONObject message) {
   223         // Everything here is synchronous and serial, so we need not worry about
   224         // overwriting an in-progress response.
   225         try {
   226             if (event.equals("SharedPreferences:Set")) {
   227                 if (Log.isLoggable(LOGTAG, Log.VERBOSE)) {
   228                     Log.v(LOGTAG, "Got SharedPreferences:Set message.");
   229                 }
   230                 handleSet(message);
   231             } else if (event.equals("SharedPreferences:Get")) {
   232                 if (Log.isLoggable(LOGTAG, Log.VERBOSE)) {
   233                     Log.v(LOGTAG, "Got SharedPreferences:Get message.");
   234                 }
   235                 JSONObject obj = new JSONObject();
   236                 obj.put("values", handleGet(message));
   237                 EventDispatcher.sendResponse(message, obj);
   238             } else if (event.equals("SharedPreferences:Observe")) {
   239                 if (Log.isLoggable(LOGTAG, Log.VERBOSE)) {
   240                     Log.v(LOGTAG, "Got SharedPreferences:Observe message.");
   241                 }
   242                 handleObserve(message);
   243             } else {
   244                 Log.e(LOGTAG, "SharedPreferencesHelper got unexpected message " + event);
   245                 return;
   246             }
   247         } catch (JSONException e) {
   248             Log.e(LOGTAG, "Got exception in handleMessage handling event " + event, e);
   249             return;
   250         }
   251     }
   252 }

mercurial