blob: a27723e27b09f57cbc178e8e5e34f313f9ddad6f [file] [log] [blame]
/*
* 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);
}
}
}