/* * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.quicksearchbox; import com.android.quicksearchbox.util.NamedTask; import com.android.quicksearchbox.util.NamedTaskExecutor; import android.util.Log; import java.util.Collections; import java.util.HashSet; import java.util.Set; /** * Refreshes shortcuts from their source. */ class SourceShortcutRefresher implements ShortcutRefresher { private static final String TAG = "QSB.SourceShortcutRefresher"; private static final boolean DBG = false; private final NamedTaskExecutor mExecutor; private final Set<String> mRefreshed = Collections.synchronizedSet(new HashSet<String>()); private final Set<String> mRefreshing = Collections.synchronizedSet(new HashSet<String>()); /** * Create a ShortcutRefresher that will refresh shortcuts using the given executor. * * @param executor Used to execute the tasks. */ public SourceShortcutRefresher(NamedTaskExecutor executor) { mExecutor = executor; } public void refresh(Suggestion shortcut, Listener listener) { Source source = shortcut.getSuggestionSource(); if (source == null) { throw new NullPointerException("source"); } String shortcutId = shortcut.getShortcutId(); if (shouldRefresh(source, shortcutId) && !isRefreshing(source, shortcutId)) { if (DBG) { Log.d(TAG, "Refreshing shortcut " + shortcutId + " '" + shortcut.getSuggestionText1() + "'"); } markShortcutRefreshing(source, shortcutId); String extraData = shortcut.getSuggestionIntentExtraData(); ShortcutRefreshTask refreshTask = new ShortcutRefreshTask( source, shortcutId, extraData, listener); mExecutor.execute(refreshTask); } } /** * Returns true if the given shortcut requires refreshing. */ public boolean shouldRefresh(Source source, String shortcutId) { return source != null && shortcutId != null && !mRefreshed.contains(makeKey(source, shortcutId)); } public boolean isRefreshing(Source source, String shortcutId) { return source != null && shortcutId != null && mRefreshing.contains(makeKey(source, shortcutId)); } private void markShortcutRefreshing(Source source, String shortcutId) { mRefreshing.add(makeKey(source, shortcutId)); } /** * Indicate that the shortcut no longer requires refreshing. */ public void markShortcutRefreshed(Source source, String shortcutId) { String key = makeKey(source, shortcutId); mRefreshed.add(key); mRefreshing.remove(key); } /** * Reset internal state. This results in all shortcuts requiring refreshing. */ public void reset() { mRefreshed.clear(); } private static String makeKey(Source source, String shortcutId) { return source.getName() + "#" + shortcutId; } /** * Refreshes a shortcut with a source and reports the result to a * {@link ShortcutRefresher.Listener}. */ private class ShortcutRefreshTask implements NamedTask { private final Source mSource; private final String mShortcutId; private final String mExtraData; private final Listener mListener; /** * @param source The source that should validate the shortcut. * @param shortcutId The shortcut to be refreshed. * @param listener Who to report back to when the result is in. */ ShortcutRefreshTask(Source source, String shortcutId, String extraData, Listener listener) { mSource = source; mShortcutId = shortcutId; mExtraData = extraData; mListener = listener; } public String getName() { return mSource.getName(); } public void run() { // TODO: Add latency tracking and logging. SuggestionCursor refreshed = mSource.refreshShortcut(mShortcutId, mExtraData); // Close cursor if empty and pass null as the refreshed cursor if (refreshed != null && refreshed.getCount() == 0) { refreshed.close(); refreshed = null; } markShortcutRefreshed(mSource, mShortcutId); mListener.onShortcutRefreshed(mSource, mShortcutId, refreshed); } } }