summaryrefslogtreecommitdiffstats
path: root/mobile/android/base/java/org/mozilla/gecko/home/HomePanelsManager.java
diff options
context:
space:
mode:
Diffstat (limited to 'mobile/android/base/java/org/mozilla/gecko/home/HomePanelsManager.java')
-rw-r--r--mobile/android/base/java/org/mozilla/gecko/home/HomePanelsManager.java368
1 files changed, 0 insertions, 368 deletions
diff --git a/mobile/android/base/java/org/mozilla/gecko/home/HomePanelsManager.java b/mobile/android/base/java/org/mozilla/gecko/home/HomePanelsManager.java
deleted file mode 100644
index bfd6c5624..000000000
--- a/mobile/android/base/java/org/mozilla/gecko/home/HomePanelsManager.java
+++ /dev/null
@@ -1,368 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.home;
-
-import static org.mozilla.gecko.home.HomeConfig.createBuiltinPanelConfig;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Queue;
-import java.util.Set;
-import java.util.concurrent.ConcurrentLinkedQueue;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.mozilla.gecko.db.HomeProvider;
-import org.mozilla.gecko.EventDispatcher;
-import org.mozilla.gecko.home.HomeConfig.PanelConfig;
-import org.mozilla.gecko.home.PanelInfoManager.PanelInfo;
-import org.mozilla.gecko.home.PanelInfoManager.RequestCallback;
-import org.mozilla.gecko.util.GeckoEventListener;
-import org.mozilla.gecko.util.ThreadUtils;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.os.Handler;
-import android.util.Log;
-
-public class HomePanelsManager implements GeckoEventListener {
- public static final String LOGTAG = "HomePanelsManager";
-
- private static final HomePanelsManager sInstance = new HomePanelsManager();
-
- private static final int INVALIDATION_DELAY_MSEC = 500;
- private static final int PANEL_INFO_TIMEOUT_MSEC = 1000;
-
- private static final String EVENT_HOMEPANELS_INSTALL = "HomePanels:Install";
- private static final String EVENT_HOMEPANELS_UNINSTALL = "HomePanels:Uninstall";
- private static final String EVENT_HOMEPANELS_UPDATE = "HomePanels:Update";
- private static final String EVENT_HOMEPANELS_REFRESH = "HomePanels:RefreshDataset";
-
- private static final String JSON_KEY_PANEL = "panel";
- private static final String JSON_KEY_PANEL_ID = "id";
-
- private enum ChangeType {
- UNINSTALL,
- INSTALL,
- UPDATE,
- REFRESH
- }
-
- private enum InvalidationMode {
- DELAYED,
- IMMEDIATE
- }
-
- private static class ConfigChange {
- private final ChangeType type;
- private final Object target;
-
- public ConfigChange(ChangeType type) {
- this(type, null);
- }
-
- public ConfigChange(ChangeType type, Object target) {
- this.type = type;
- this.target = target;
- }
- }
-
- private Context mContext;
- private HomeConfig mHomeConfig;
- private boolean mInitialized;
-
- private final Queue<ConfigChange> mPendingChanges = new ConcurrentLinkedQueue<ConfigChange>();
- private final Runnable mInvalidationRunnable = new InvalidationRunnable();
-
- public static HomePanelsManager getInstance() {
- return sInstance;
- }
-
- public void init(Context context) {
- if (mInitialized) {
- return;
- }
-
- mContext = context;
- mHomeConfig = HomeConfig.getDefault(context);
-
- EventDispatcher.getInstance().registerGeckoThreadListener(this,
- EVENT_HOMEPANELS_INSTALL,
- EVENT_HOMEPANELS_UNINSTALL,
- EVENT_HOMEPANELS_UPDATE,
- EVENT_HOMEPANELS_REFRESH);
-
- mInitialized = true;
- }
-
- public void onLocaleReady(final String locale) {
- ThreadUtils.getBackgroundHandler().post(new Runnable() {
- @Override
- public void run() {
- final String configLocale = mHomeConfig.getLocale();
- if (configLocale == null || !configLocale.equals(locale)) {
- handleLocaleChange();
- }
- }
- });
- }
-
- @Override
- public void handleMessage(String event, JSONObject message) {
- try {
- if (event.equals(EVENT_HOMEPANELS_INSTALL)) {
- Log.d(LOGTAG, EVENT_HOMEPANELS_INSTALL);
- handlePanelInstall(createPanelConfigFromMessage(message), InvalidationMode.DELAYED);
- } else if (event.equals(EVENT_HOMEPANELS_UNINSTALL)) {
- Log.d(LOGTAG, EVENT_HOMEPANELS_UNINSTALL);
- final String panelId = message.getString(JSON_KEY_PANEL_ID);
- handlePanelUninstall(panelId);
- } else if (event.equals(EVENT_HOMEPANELS_UPDATE)) {
- Log.d(LOGTAG, EVENT_HOMEPANELS_UPDATE);
- handlePanelUpdate(createPanelConfigFromMessage(message));
- } else if (event.equals(EVENT_HOMEPANELS_REFRESH)) {
- Log.d(LOGTAG, EVENT_HOMEPANELS_REFRESH);
- handleDatasetRefresh(message);
- }
- } catch (Exception e) {
- Log.e(LOGTAG, "Failed to handle event " + event, e);
- }
- }
-
- private PanelConfig createPanelConfigFromMessage(JSONObject message) throws JSONException {
- final JSONObject json = message.getJSONObject(JSON_KEY_PANEL);
- return new PanelConfig(json);
- }
-
- /**
- * Adds a new PanelConfig to the HomeConfig.
- *
- * This posts the invalidation of HomeConfig immediately.
- *
- * @param panelConfig panel to add
- */
- public void installPanel(PanelConfig panelConfig) {
- Log.d(LOGTAG, "installPanel: " + panelConfig.getTitle());
- handlePanelInstall(panelConfig, InvalidationMode.IMMEDIATE);
- }
-
- /**
- * Runs in the gecko thread.
- */
- private void handlePanelInstall(PanelConfig panelConfig, InvalidationMode mode) {
- mPendingChanges.offer(new ConfigChange(ChangeType.INSTALL, panelConfig));
- Log.d(LOGTAG, "handlePanelInstall: " + mPendingChanges.size());
-
- scheduleInvalidation(mode);
- }
-
- /**
- * Runs in the gecko thread.
- */
- private void handlePanelUninstall(String panelId) {
- mPendingChanges.offer(new ConfigChange(ChangeType.UNINSTALL, panelId));
- Log.d(LOGTAG, "handlePanelUninstall: " + mPendingChanges.size());
-
- scheduleInvalidation(InvalidationMode.DELAYED);
- }
-
- /**
- * Runs in the gecko thread.
- */
- private void handlePanelUpdate(PanelConfig panelConfig) {
- mPendingChanges.offer(new ConfigChange(ChangeType.UPDATE, panelConfig));
- Log.d(LOGTAG, "handlePanelUpdate: " + mPendingChanges.size());
-
- scheduleInvalidation(InvalidationMode.DELAYED);
- }
-
- /**
- * Runs in the background thread.
- */
- private void handleLocaleChange() {
- mPendingChanges.offer(new ConfigChange(ChangeType.REFRESH));
- Log.d(LOGTAG, "handleLocaleChange: " + mPendingChanges.size());
-
- scheduleInvalidation(InvalidationMode.IMMEDIATE);
- }
-
-
- /**
- * Handles a dataset refresh request from Gecko. This is usually
- * triggered by a HomeStorage.save() call in an add-on.
- *
- * Runs in the gecko thread.
- */
- private void handleDatasetRefresh(JSONObject message) {
- final String datasetId;
- try {
- datasetId = message.getString("datasetId");
- } catch (JSONException e) {
- Log.e(LOGTAG, "Failed to handle dataset refresh", e);
- return;
- }
-
- Log.d(LOGTAG, "Refresh request for dataset: " + datasetId);
-
- final ContentResolver cr = mContext.getContentResolver();
- cr.notifyChange(HomeProvider.getDatasetNotificationUri(datasetId), null);
- }
-
- /**
- * Runs in the gecko or main thread.
- */
- private void scheduleInvalidation(InvalidationMode mode) {
- final Handler handler = ThreadUtils.getBackgroundHandler();
-
- handler.removeCallbacks(mInvalidationRunnable);
-
- if (mode == InvalidationMode.IMMEDIATE) {
- handler.post(mInvalidationRunnable);
- } else {
- handler.postDelayed(mInvalidationRunnable, INVALIDATION_DELAY_MSEC);
- }
-
- Log.d(LOGTAG, "scheduleInvalidation: scheduled new invalidation: " + mode);
- }
-
- /**
- * Runs in the background thread.
- */
- private void executePendingChanges(HomeConfig.Editor editor) {
- boolean shouldRefresh = false;
-
- while (!mPendingChanges.isEmpty()) {
- final ConfigChange pendingChange = mPendingChanges.poll();
-
- switch (pendingChange.type) {
- case UNINSTALL: {
- final String panelId = (String) pendingChange.target;
- if (editor.uninstall(panelId)) {
- Log.d(LOGTAG, "executePendingChanges: uninstalled panel " + panelId);
- }
- break;
- }
-
- case INSTALL: {
- final PanelConfig panelConfig = (PanelConfig) pendingChange.target;
- if (editor.install(panelConfig)) {
- Log.d(LOGTAG, "executePendingChanges: added panel " + panelConfig.getId());
- }
- break;
- }
-
- case UPDATE: {
- final PanelConfig panelConfig = (PanelConfig) pendingChange.target;
- if (editor.update(panelConfig)) {
- Log.w(LOGTAG, "executePendingChanges: updated panel " + panelConfig.getId());
- }
- break;
- }
-
- case REFRESH: {
- shouldRefresh = true;
- }
- }
- }
-
- // The editor still represents the default HomeConfig
- // configuration and hasn't been changed by any operation
- // above. No need to refresh as the HomeConfig backend will
- // take of forcing all existing HomeConfigLoader instances to
- // refresh their contents.
- if (shouldRefresh && !editor.isDefault()) {
- executeRefresh(editor);
- }
- }
-
- /**
- * Runs in the background thread.
- */
- private void refreshFromPanelInfos(HomeConfig.Editor editor, List<PanelInfo> panelInfos) {
- Log.d(LOGTAG, "refreshFromPanelInfos");
-
- for (PanelConfig panelConfig : editor) {
- PanelConfig refreshedPanelConfig = null;
-
- if (panelConfig.isDynamic()) {
- for (PanelInfo panelInfo : panelInfos) {
- if (panelInfo.getId().equals(panelConfig.getId())) {
- refreshedPanelConfig = panelInfo.toPanelConfig();
- Log.d(LOGTAG, "refreshFromPanelInfos: refreshing from panel info: " + panelInfo.getId());
- break;
- }
- }
- } else {
- refreshedPanelConfig = createBuiltinPanelConfig(mContext, panelConfig.getType());
- Log.d(LOGTAG, "refreshFromPanelInfos: refreshing built-in panel: " + panelConfig.getId());
- }
-
- if (refreshedPanelConfig == null) {
- Log.d(LOGTAG, "refreshFromPanelInfos: no refreshed panel, falling back: " + panelConfig.getId());
- continue;
- }
-
- Log.d(LOGTAG, "refreshFromPanelInfos: refreshed panel " + refreshedPanelConfig.getId());
- editor.update(refreshedPanelConfig);
- }
- }
-
- /**
- * Runs in the background thread.
- */
- private void executeRefresh(HomeConfig.Editor editor) {
- if (editor.isEmpty()) {
- return;
- }
-
- Log.d(LOGTAG, "executeRefresh");
-
- final Set<String> ids = new HashSet<String>();
- for (PanelConfig panelConfig : editor) {
- ids.add(panelConfig.getId());
- }
-
- final Object panelRequestLock = new Object();
- final List<PanelInfo> latestPanelInfos = new ArrayList<PanelInfo>();
-
- final PanelInfoManager pm = new PanelInfoManager();
- pm.requestPanelsById(ids, new RequestCallback() {
- @Override
- public void onComplete(List<PanelInfo> panelInfos) {
- synchronized (panelRequestLock) {
- latestPanelInfos.addAll(panelInfos);
- Log.d(LOGTAG, "executeRefresh: fetched panel infos: " + panelInfos.size());
-
- panelRequestLock.notifyAll();
- }
- }
- });
-
- try {
- synchronized (panelRequestLock) {
- panelRequestLock.wait(PANEL_INFO_TIMEOUT_MSEC);
-
- Log.d(LOGTAG, "executeRefresh: done fetching panel infos");
- refreshFromPanelInfos(editor, latestPanelInfos);
- }
- } catch (InterruptedException e) {
- Log.e(LOGTAG, "Failed to fetch panels from gecko", e);
- }
- }
-
- /**
- * Runs in the background thread.
- */
- private class InvalidationRunnable implements Runnable {
- @Override
- public void run() {
- final HomeConfig.Editor editor = mHomeConfig.load().edit();
- executePendingChanges(editor);
- editor.apply();
- }
- };
-}