ShortcutRefresher.java revision 94e8a2be78530170f50e7895a558bf8011bbf8e8
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 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 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 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. 15 */ 16 17package com.android.quicksearchbox; 18 19import android.content.ComponentName; 20 21import java.util.Collections; 22import java.util.HashSet; 23import java.util.Set; 24 25/** 26 * Fires off tasks to validate shortcuts, and reports the results back to a 27 * {@link Listener}. 28 */ 29class ShortcutRefresher { 30 31 public interface Listener { 32 /** 33 * Called by the ShortcutRefresher when a shortcut has been refreshed. 34 * 35 * @param componentName of the source of this shortcut. 36 * @param shortcutId the id of the shortcut. 37 * @param refreshed the updated shortcut, or {@code null} if the shortcut 38 * is no longer valid and should be deleted. 39 */ 40 void onShortcutRefreshed(ComponentName componentName, String shortcutId, 41 SuggestionCursor refreshed); 42 } 43 44 private final SourceTaskExecutor mExecutor; 45 private final SourceLookup mSourceLookup; 46 47 private final Set<String> mRefreshed = Collections.synchronizedSet(new HashSet<String>()); 48 49 /** 50 * Create a ShortcutRefresher that will refresh shortcuts using the given executor. 51 * 52 * @param executor Used to execute the tasks. 53 * @param sourceLookup Used to lookup suggestion sources by component name. 54 */ 55 public ShortcutRefresher(SourceTaskExecutor executor, SourceLookup sourceLookup) { 56 mExecutor = executor; 57 mSourceLookup = sourceLookup; 58 } 59 60 /** 61 * Sends off the refresher tasks. 62 * 63 * @param shortcuts The shortcuts to refresh. 64 * @param listener Who to report back to. 65 */ 66 public void refresh(SuggestionCursor shortcuts, final Listener listener) { 67 int count = shortcuts.getCount(); 68 for (int i = 0; i < count; i++) { 69 shortcuts.moveTo(i); 70 if (shouldRefresh(shortcuts)) { 71 String shortcutId = shortcuts.getShortcutId(); 72 ComponentName componentName = shortcuts.getSourceComponentName(); 73 Source source = mSourceLookup.getSourceByComponentName(componentName); 74 75 // If we can't find the source then invalidate the shortcut. 76 // Otherwise, send off the refresh task. 77 if (source == null) { 78 listener.onShortcutRefreshed(componentName, shortcutId, null); 79 } else { 80 String extraData = shortcuts.getSuggestionIntentExtraData(); 81 ShortcutRefreshTask refreshTask = new ShortcutRefreshTask( 82 source, shortcutId, extraData, listener); 83 mExecutor.execute(refreshTask); 84 } 85 } 86 } 87 } 88 89 /** 90 * Returns true if the given shortcut requires refreshing. 91 */ 92 public boolean shouldRefresh(SuggestionCursor shortcut) { 93 return shortcut.getShortcutId() != null 94 && ! mRefreshed.contains(makeKey(shortcut)); 95 } 96 97 /** 98 * Indicate that the shortcut no longer requires refreshing. 99 */ 100 public void onShortcutRefreshed(SuggestionCursor shortcut) { 101 mRefreshed.add(makeKey(shortcut)); 102 } 103 104 /** 105 * Reset internal state. This results in all shortcuts requiring refreshing. 106 */ 107 public void reset() { 108 mRefreshed.clear(); 109 } 110 111 /** 112 * Cancel any pending shortcut refresh requests. 113 */ 114 public void cancelPendingTasks() { 115 mExecutor.cancelPendingTasks(); 116 } 117 118 private static String makeKey(SuggestionCursor shortcut) { 119 return shortcut.getSourceComponentName().flattenToShortString() + "#" 120 + shortcut.getShortcutId(); 121 } 122 123 /** 124 * Refreshes a shortcut with a source and reports the result to a {@link Listener}. 125 */ 126 private class ShortcutRefreshTask implements SourceTask { 127 private final Source mSource; 128 private final String mShortcutId; 129 private final String mExtraData; 130 private final Listener mListener; 131 132 /** 133 * @param source The source that should validate the shortcut. 134 * @param shortcutId The shortcut to be refreshed. 135 * @param listener Who to report back to when the result is in. 136 */ 137 ShortcutRefreshTask(Source source, String shortcutId, String extraData, 138 Listener listener) { 139 mSource = source; 140 mShortcutId = shortcutId; 141 mExtraData = extraData; 142 mListener = listener; 143 } 144 145 public void run() { 146 // TODO: Add latency tracking and logging. 147 SuggestionCursor refreshed = mSource.refreshShortcut(mShortcutId, mExtraData); 148 onShortcutRefreshed(refreshed); 149 mListener.onShortcutRefreshed(mSource.getComponentName(), mShortcutId, refreshed); 150 } 151 152 public Source getSource() { 153 return mSource; 154 } 155 } 156} 157