mobile/android/base/home/HomeConfigPrefsBackend.java

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/mobile/android/base/home/HomeConfigPrefsBackend.java	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,217 @@
     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.home;
    1.10 +
    1.11 +import static org.mozilla.gecko.home.HomeConfig.createBuiltinPanelConfig;
    1.12 +
    1.13 +import java.util.ArrayList;
    1.14 +import java.util.EnumSet;
    1.15 +import java.util.List;
    1.16 +import java.util.Locale;
    1.17 +
    1.18 +import org.json.JSONArray;
    1.19 +import org.json.JSONException;
    1.20 +import org.json.JSONObject;
    1.21 +import org.mozilla.gecko.GeckoSharedPrefs;
    1.22 +import org.mozilla.gecko.home.HomeConfig.HomeConfigBackend;
    1.23 +import org.mozilla.gecko.home.HomeConfig.OnReloadListener;
    1.24 +import org.mozilla.gecko.home.HomeConfig.PanelConfig;
    1.25 +import org.mozilla.gecko.home.HomeConfig.PanelType;
    1.26 +import org.mozilla.gecko.home.HomeConfig.State;
    1.27 +import org.mozilla.gecko.util.HardwareUtils;
    1.28 +
    1.29 +import android.content.BroadcastReceiver;
    1.30 +import android.content.Context;
    1.31 +import android.content.Intent;
    1.32 +import android.content.IntentFilter;
    1.33 +import android.content.SharedPreferences;
    1.34 +import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
    1.35 +import android.support.v4.content.LocalBroadcastManager;
    1.36 +import android.text.TextUtils;
    1.37 +import android.util.Log;
    1.38 +
    1.39 +class HomeConfigPrefsBackend implements HomeConfigBackend {
    1.40 +    private static final String LOGTAG = "GeckoHomeConfigBackend";
    1.41 +
    1.42 +    private static final String PREFS_CONFIG_KEY = "home_panels";
    1.43 +    private static final String PREFS_LOCALE_KEY = "home_locale";
    1.44 +
    1.45 +    private static final String RELOAD_BROADCAST = "HomeConfigPrefsBackend:Reload";
    1.46 +
    1.47 +    private final Context mContext;
    1.48 +    private ReloadBroadcastReceiver mReloadBroadcastReceiver;
    1.49 +    private OnReloadListener mReloadListener;
    1.50 +
    1.51 +    public HomeConfigPrefsBackend(Context context) {
    1.52 +        mContext = context;
    1.53 +    }
    1.54 +
    1.55 +    private SharedPreferences getSharedPreferences() {
    1.56 +        return GeckoSharedPrefs.forProfile(mContext);
    1.57 +    }
    1.58 +
    1.59 +    private State loadDefaultConfig() {
    1.60 +        final ArrayList<PanelConfig> panelConfigs = new ArrayList<PanelConfig>();
    1.61 +
    1.62 +        panelConfigs.add(createBuiltinPanelConfig(mContext, PanelType.TOP_SITES,
    1.63 +                                                  EnumSet.of(PanelConfig.Flags.DEFAULT_PANEL)));
    1.64 +
    1.65 +        panelConfigs.add(createBuiltinPanelConfig(mContext, PanelType.BOOKMARKS));
    1.66 +
    1.67 +        // We disable reader mode support on low memory devices. Hence the
    1.68 +        // reading list panel should not show up on such devices.
    1.69 +        if (!HardwareUtils.isLowMemoryPlatform()) {
    1.70 +            panelConfigs.add(createBuiltinPanelConfig(mContext, PanelType.READING_LIST));
    1.71 +        }
    1.72 +
    1.73 +        final PanelConfig historyEntry = createBuiltinPanelConfig(mContext, PanelType.HISTORY);
    1.74 +
    1.75 +        // On tablets, the history panel is the last.
    1.76 +        // On phones, the history panel is the first one.
    1.77 +        if (HardwareUtils.isTablet()) {
    1.78 +            panelConfigs.add(historyEntry);
    1.79 +        } else {
    1.80 +            panelConfigs.add(0, historyEntry);
    1.81 +        }
    1.82 +
    1.83 +        return new State(panelConfigs, true);
    1.84 +    }
    1.85 +
    1.86 +    private State loadConfigFromString(String jsonString) {
    1.87 +        final JSONArray jsonPanelConfigs;
    1.88 +        try {
    1.89 +            jsonPanelConfigs = new JSONArray(jsonString);
    1.90 +        } catch (JSONException e) {
    1.91 +            Log.e(LOGTAG, "Error loading the list of home panels from JSON prefs", e);
    1.92 +
    1.93 +            // Fallback to default config
    1.94 +            return loadDefaultConfig();
    1.95 +        }
    1.96 +
    1.97 +        final ArrayList<PanelConfig> panelConfigs = new ArrayList<PanelConfig>();
    1.98 +
    1.99 +        final int count = jsonPanelConfigs.length();
   1.100 +        for (int i = 0; i < count; i++) {
   1.101 +            try {
   1.102 +                final JSONObject jsonPanelConfig = jsonPanelConfigs.getJSONObject(i);
   1.103 +                final PanelConfig panelConfig = new PanelConfig(jsonPanelConfig);
   1.104 +                panelConfigs.add(panelConfig);
   1.105 +            } catch (Exception e) {
   1.106 +                Log.e(LOGTAG, "Exception loading PanelConfig from JSON", e);
   1.107 +            }
   1.108 +        }
   1.109 +
   1.110 +        return new State(panelConfigs, false);
   1.111 +    }
   1.112 +
   1.113 +    @Override
   1.114 +    public State load() {
   1.115 +        final SharedPreferences prefs = getSharedPreferences();
   1.116 +        final String jsonString = prefs.getString(PREFS_CONFIG_KEY, null);
   1.117 +
   1.118 +        final State configState;
   1.119 +        if (TextUtils.isEmpty(jsonString)) {
   1.120 +            configState = loadDefaultConfig();
   1.121 +        } else {
   1.122 +            configState = loadConfigFromString(jsonString);
   1.123 +        }
   1.124 +
   1.125 +        return configState;
   1.126 +    }
   1.127 +
   1.128 +    @Override
   1.129 +    public void save(State configState) {
   1.130 +        final SharedPreferences prefs = getSharedPreferences();
   1.131 +        final SharedPreferences.Editor editor = prefs.edit();
   1.132 +
   1.133 +        // No need to save the state to disk if it represents the default
   1.134 +        // HomeConfig configuration. Simply force all existing HomeConfigLoader
   1.135 +        // instances to refresh their contents.
   1.136 +        if (!configState.isDefault()) {
   1.137 +            final JSONArray jsonPanelConfigs = new JSONArray();
   1.138 +
   1.139 +            for (PanelConfig panelConfig : configState) {
   1.140 +                try {
   1.141 +                    final JSONObject jsonPanelConfig = panelConfig.toJSON();
   1.142 +                    jsonPanelConfigs.put(jsonPanelConfig);
   1.143 +                } catch (Exception e) {
   1.144 +                    Log.e(LOGTAG, "Exception converting PanelConfig to JSON", e);
   1.145 +                }
   1.146 +            }
   1.147 +
   1.148 +            editor.putString(PREFS_CONFIG_KEY, jsonPanelConfigs.toString());
   1.149 +        }
   1.150 +
   1.151 +        editor.putString(PREFS_LOCALE_KEY, Locale.getDefault().toString());
   1.152 +        editor.commit();
   1.153 +
   1.154 +        // Trigger reload listeners on all live backend instances
   1.155 +        sendReloadBroadcast();
   1.156 +    }
   1.157 +
   1.158 +    @Override
   1.159 +    public String getLocale() {
   1.160 +        final SharedPreferences prefs = getSharedPreferences();
   1.161 +
   1.162 +        String locale = prefs.getString(PREFS_LOCALE_KEY, null);
   1.163 +        if (locale == null) {
   1.164 +            // Initialize config with the current locale
   1.165 +            final String currentLocale = Locale.getDefault().toString();
   1.166 +
   1.167 +            final SharedPreferences.Editor editor = prefs.edit();
   1.168 +            editor.putString(PREFS_LOCALE_KEY, currentLocale);
   1.169 +            editor.commit();
   1.170 +
   1.171 +            // If the user has saved HomeConfig before, return null this
   1.172 +            // one time to trigger a refresh and ensure we use the
   1.173 +            // correct locale for the saved state. For more context,
   1.174 +            // see HomePanelsManager.onLocaleReady().
   1.175 +            if (!prefs.contains(PREFS_CONFIG_KEY)) {
   1.176 +                locale = currentLocale;
   1.177 +            }
   1.178 +        }
   1.179 +
   1.180 +        return locale;
   1.181 +    }
   1.182 +
   1.183 +    @Override
   1.184 +    public void setOnReloadListener(OnReloadListener listener) {
   1.185 +        if (mReloadListener != null) {
   1.186 +            unregisterReloadReceiver();
   1.187 +            mReloadBroadcastReceiver = null;
   1.188 +        }
   1.189 +
   1.190 +        mReloadListener = listener;
   1.191 +
   1.192 +        if (mReloadListener != null) {
   1.193 +            mReloadBroadcastReceiver = new ReloadBroadcastReceiver();
   1.194 +            registerReloadReceiver();
   1.195 +        }
   1.196 +    }
   1.197 +
   1.198 +    private void sendReloadBroadcast() {
   1.199 +        final LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(mContext);
   1.200 +        final Intent reloadIntent = new Intent(RELOAD_BROADCAST);
   1.201 +        lbm.sendBroadcast(reloadIntent);
   1.202 +    }
   1.203 +
   1.204 +    private void registerReloadReceiver() {
   1.205 +        final LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(mContext);
   1.206 +        lbm.registerReceiver(mReloadBroadcastReceiver, new IntentFilter(RELOAD_BROADCAST));
   1.207 +    }
   1.208 +
   1.209 +    private void unregisterReloadReceiver() {
   1.210 +        final LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(mContext);
   1.211 +        lbm.unregisterReceiver(mReloadBroadcastReceiver);
   1.212 +    }
   1.213 +
   1.214 +    private class ReloadBroadcastReceiver extends BroadcastReceiver {
   1.215 +        @Override
   1.216 +        public void onReceive(Context context, Intent intent) {
   1.217 +            mReloadListener.onReload();
   1.218 +        }
   1.219 +    }
   1.220 +}

mercurial