• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package com.android.quicksearchbox;
18 
19 import com.android.quicksearchbox.util.NamedTask;
20 import com.android.quicksearchbox.util.NamedTaskExecutor;
21 
22 import android.util.Log;
23 
24 import java.util.Collections;
25 import java.util.HashSet;
26 import java.util.Set;
27 
28 /**
29  * Refreshes shortcuts from their source.
30  */
31 class SourceShortcutRefresher implements ShortcutRefresher {
32     private static final String TAG = "QSB.SourceShortcutRefresher";
33     private static final boolean DBG = false;
34 
35     private final NamedTaskExecutor mExecutor;
36 
37     private final Set<String> mRefreshed = Collections.synchronizedSet(new HashSet<String>());
38     private final Set<String> mRefreshing = Collections.synchronizedSet(new HashSet<String>());
39 
40     /**
41      * Create a ShortcutRefresher that will refresh shortcuts using the given executor.
42      *
43      * @param executor Used to execute the tasks.
44      */
SourceShortcutRefresher(NamedTaskExecutor executor)45     public SourceShortcutRefresher(NamedTaskExecutor executor) {
46         mExecutor = executor;
47     }
48 
refresh(Suggestion shortcut, Listener listener)49     public void refresh(Suggestion shortcut, Listener listener) {
50         Source source = shortcut.getSuggestionSource();
51         if (source == null) {
52             throw new NullPointerException("source");
53         }
54         String shortcutId = shortcut.getShortcutId();
55         if (shouldRefresh(source, shortcutId) && !isRefreshing(source, shortcutId)) {
56             if (DBG) {
57                 Log.d(TAG, "Refreshing shortcut  " + shortcutId + " '" +
58                         shortcut.getSuggestionText1() + "'");
59             }
60             markShortcutRefreshing(source, shortcutId);
61             String extraData = shortcut.getSuggestionIntentExtraData();
62             ShortcutRefreshTask refreshTask = new ShortcutRefreshTask(
63                     source, shortcutId, extraData, listener);
64             mExecutor.execute(refreshTask);
65         }
66     }
67 
68     /**
69      * Returns true if the given shortcut requires refreshing.
70      */
shouldRefresh(Source source, String shortcutId)71     public boolean shouldRefresh(Source source, String shortcutId) {
72         return source != null && shortcutId != null
73                 && !mRefreshed.contains(makeKey(source, shortcutId));
74     }
75 
isRefreshing(Source source, String shortcutId)76     public boolean isRefreshing(Source source, String shortcutId) {
77         return source != null && shortcutId != null
78                 && mRefreshing.contains(makeKey(source, shortcutId));
79     }
80 
markShortcutRefreshing(Source source, String shortcutId)81     private void markShortcutRefreshing(Source source, String shortcutId) {
82         mRefreshing.add(makeKey(source, shortcutId));
83     }
84 
85     /**
86      * Indicate that the shortcut no longer requires refreshing.
87      */
markShortcutRefreshed(Source source, String shortcutId)88     public void markShortcutRefreshed(Source source, String shortcutId) {
89         String key = makeKey(source, shortcutId);
90         mRefreshed.add(key);
91         mRefreshing.remove(key);
92     }
93 
94     /**
95      * Reset internal state.  This results in all shortcuts requiring refreshing.
96      */
reset()97     public void reset() {
98         mRefreshed.clear();
99     }
100 
makeKey(Source source, String shortcutId)101     private static String makeKey(Source source, String shortcutId) {
102         return source.getName() + "#" + shortcutId;
103     }
104 
105     /**
106      * Refreshes a shortcut with a source and reports the result to a
107      * {@link ShortcutRefresher.Listener}.
108      */
109     private class ShortcutRefreshTask implements NamedTask {
110         private final Source mSource;
111         private final String mShortcutId;
112         private final String mExtraData;
113         private final Listener mListener;
114 
115         /**
116          * @param source The source that should validate the shortcut.
117          * @param shortcutId The shortcut to be refreshed.
118          * @param listener Who to report back to when the result is in.
119          */
ShortcutRefreshTask(Source source, String shortcutId, String extraData, Listener listener)120         ShortcutRefreshTask(Source source, String shortcutId, String extraData,
121                 Listener listener) {
122             mSource = source;
123             mShortcutId = shortcutId;
124             mExtraData = extraData;
125             mListener = listener;
126         }
127 
getName()128         public String getName() {
129             return mSource.getName();
130         }
131 
run()132         public void run() {
133             // TODO: Add latency tracking and logging.
134             SuggestionCursor refreshed = mSource.refreshShortcut(mShortcutId, mExtraData);
135             // Close cursor if empty and pass null as the refreshed cursor
136             if (refreshed != null && refreshed.getCount() == 0) {
137                 refreshed.close();
138                 refreshed = null;
139             }
140             markShortcutRefreshed(mSource, mShortcutId);
141             mListener.onShortcutRefreshed(mSource, mShortcutId, refreshed);
142         }
143 
144     }
145 }
146