2 * Copyright (C) 2010 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.android.quicksearchbox;
19 import com.android.quicksearchbox.util.NamedTask;
20 import com.android.quicksearchbox.util.NamedTaskExecutor;
22 import android.util.Log;
24 import java.util.Collections;
25 import java.util.HashSet;
29 * Refreshes shortcuts from their source.
31 class SourceShortcutRefresher implements ShortcutRefresher {
32 private static final String TAG = "QSB.SourceShortcutRefresher";
33 private static final boolean DBG = false;
35 private final NamedTaskExecutor mExecutor;
37 private final Set<String> mRefreshed = Collections.synchronizedSet(new HashSet<String>());
38 private final Set<String> mRefreshing = Collections.synchronizedSet(new HashSet<String>());
41 * Create a ShortcutRefresher that will refresh shortcuts using the given executor.
43 * @param executor Used to execute the tasks.
45 public SourceShortcutRefresher(NamedTaskExecutor executor) {
49 public void refresh(Suggestion shortcut, Listener listener) {
50 Source source = shortcut.getSuggestionSource();
52 throw new NullPointerException("source");
54 String shortcutId = shortcut.getShortcutId();
55 if (shouldRefresh(source, shortcutId) && !isRefreshing(source, shortcutId)) {
57 Log.d(TAG, "Refreshing shortcut " + shortcutId + " '" +
58 shortcut.getSuggestionText1() + "'");
60 markShortcutRefreshing(source, shortcutId);
61 String extraData = shortcut.getSuggestionIntentExtraData();
62 ShortcutRefreshTask refreshTask = new ShortcutRefreshTask(
63 source, shortcutId, extraData, listener);
64 mExecutor.execute(refreshTask);
69 * Returns true if the given shortcut requires refreshing.
71 public boolean shouldRefresh(Source source, String shortcutId) {
72 return source != null && shortcutId != null
73 && !mRefreshed.contains(makeKey(source, shortcutId));
76 public boolean isRefreshing(Source source, String shortcutId) {
77 return source != null && shortcutId != null
78 && mRefreshing.contains(makeKey(source, shortcutId));
81 private void markShortcutRefreshing(Source source, String shortcutId) {
82 mRefreshing.add(makeKey(source, shortcutId));
86 * Indicate that the shortcut no longer requires refreshing.
88 public void markShortcutRefreshed(Source source, String shortcutId) {
89 String key = makeKey(source, shortcutId);
91 mRefreshing.remove(key);
95 * Reset internal state. This results in all shortcuts requiring refreshing.
102 * Cancel any pending shortcut refresh requests.
104 public void cancelPendingTasks() {
105 mExecutor.cancelPendingTasks();
108 private static String makeKey(Source source, String shortcutId) {
109 return source.getName() + "#" + shortcutId;
113 * Refreshes a shortcut with a source and reports the result to a
114 * {@link ShortcutRefresher.Listener}.
116 private class ShortcutRefreshTask implements NamedTask {
117 private final Source mSource;
118 private final String mShortcutId;
119 private final String mExtraData;
120 private final Listener mListener;
123 * @param source The source that should validate the shortcut.
124 * @param shortcutId The shortcut to be refreshed.
125 * @param listener Who to report back to when the result is in.
127 ShortcutRefreshTask(Source source, String shortcutId, String extraData,
130 mShortcutId = shortcutId;
131 mExtraData = extraData;
132 mListener = listener;
135 public String getName() {
136 return mSource.getName();
140 // TODO: Add latency tracking and logging.
141 SuggestionCursor refreshed = mSource.refreshShortcut(mShortcutId, mExtraData);
142 // Close cursor if empty and pass null as the refreshed cursor
143 if (refreshed != null && refreshed.getCount() == 0) {
147 markShortcutRefreshed(mSource, mShortcutId);
148 mListener.onShortcutRefreshed(mSource, mShortcutId, refreshed);