OLD | NEW |
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package org.chromium.chrome.browser.searchwidget; | 5 package org.chromium.chrome.browser.searchwidget; |
6 | 6 |
7 import android.app.PendingIntent; | 7 import android.app.PendingIntent; |
8 import android.appwidget.AppWidgetManager; | 8 import android.appwidget.AppWidgetManager; |
9 import android.appwidget.AppWidgetProvider; | 9 import android.appwidget.AppWidgetProvider; |
10 import android.content.ComponentName; | 10 import android.content.ComponentName; |
11 import android.content.Context; | 11 import android.content.Context; |
12 import android.content.Intent; | 12 import android.content.Intent; |
13 import android.content.SharedPreferences; | 13 import android.content.SharedPreferences; |
14 import android.graphics.Rect; | |
15 import android.net.Uri; | 14 import android.net.Uri; |
16 import android.os.Bundle; | 15 import android.os.Bundle; |
17 import android.support.v4.app.ActivityOptionsCompat; | 16 import android.support.v4.app.ActivityOptionsCompat; |
18 import android.text.TextUtils; | 17 import android.text.TextUtils; |
19 import android.widget.RemoteViews; | 18 import android.widget.RemoteViews; |
20 | 19 |
21 import org.chromium.base.ApplicationStatus; | |
22 import org.chromium.base.ContextUtils; | 20 import org.chromium.base.ContextUtils; |
23 import org.chromium.base.Log; | 21 import org.chromium.base.Log; |
24 import org.chromium.base.ThreadUtils; | 22 import org.chromium.base.ThreadUtils; |
25 import org.chromium.base.library_loader.LibraryLoader; | 23 import org.chromium.base.library_loader.LibraryLoader; |
26 import org.chromium.chrome.R; | 24 import org.chromium.chrome.R; |
27 import org.chromium.chrome.browser.IntentHandler; | 25 import org.chromium.chrome.browser.IntentHandler; |
28 import org.chromium.chrome.browser.init.AsyncInitializationActivity; | 26 import org.chromium.chrome.browser.init.AsyncInitializationActivity; |
29 import org.chromium.chrome.browser.search_engines.TemplateUrlService; | 27 import org.chromium.chrome.browser.search_engines.TemplateUrlService; |
30 import org.chromium.chrome.browser.search_engines.TemplateUrlService.LoadListene
r; | 28 import org.chromium.chrome.browser.search_engines.TemplateUrlService.LoadListene
r; |
31 import org.chromium.chrome.browser.search_engines.TemplateUrlService.TemplateUrl
ServiceObserver; | 29 import org.chromium.chrome.browser.search_engines.TemplateUrlService.TemplateUrl
ServiceObserver; |
(...skipping 12 matching lines...) Expand all Loading... |
44 TemplateUrlService.getInstance().unregisterLoadListener(this); | 42 TemplateUrlService.getInstance().unregisterLoadListener(this); |
45 updateCachedEngineName(); | 43 updateCachedEngineName(); |
46 } | 44 } |
47 | 45 |
48 @Override | 46 @Override |
49 public void onTemplateURLServiceChanged() { | 47 public void onTemplateURLServiceChanged() { |
50 updateCachedEngineName(); | 48 updateCachedEngineName(); |
51 } | 49 } |
52 } | 50 } |
53 | 51 |
54 static final int INVALID_WIDGET_ID = -1; | |
55 | |
56 static final boolean ANIMATE_TRANSITION = false; | |
57 | |
58 private static final String ACTION_START_TEXT_QUERY = | 52 private static final String ACTION_START_TEXT_QUERY = |
59 "org.chromium.chrome.browser.searchwidget.START_TEXT_QUERY"; | 53 "org.chromium.chrome.browser.searchwidget.START_TEXT_QUERY"; |
60 private static final String ACTION_START_VOICE_QUERY = | 54 private static final String ACTION_START_VOICE_QUERY = |
61 "org.chromium.chrome.browser.searchwidget.START_VOICE_QUERY"; | 55 "org.chromium.chrome.browser.searchwidget.START_VOICE_QUERY"; |
62 private static final String ACTION_UPDATE_ALL_WIDGETS = | 56 private static final String ACTION_UPDATE_ALL_WIDGETS = |
63 "org.chromium.chrome.browser.searchwidget.UPDATE_ALL_WIDGETS"; | 57 "org.chromium.chrome.browser.searchwidget.UPDATE_ALL_WIDGETS"; |
64 | 58 |
65 static final String EXTRA_START_VOICE_SEARCH = | 59 static final String EXTRA_START_VOICE_SEARCH = |
66 "org.chromium.chrome.browser.searchwidget.START_VOICE_SEARCH"; | 60 "org.chromium.chrome.browser.searchwidget.START_VOICE_SEARCH"; |
67 private static final String EXTRA_WIDGET_ID = | |
68 "org.chromium.chrome.browser.searchwidget.WIDGET_ID"; | |
69 | 61 |
70 private static final String PREF_LAUNCHING_WIDGET_ID = | |
71 "org.chromium.chrome.browser.searchwidget.LAUNCHING_WIDGET_ID"; | |
72 private static final String PREF_SEARCH_ENGINE_SHORTNAME = | 62 private static final String PREF_SEARCH_ENGINE_SHORTNAME = |
73 "org.chromium.chrome.browser.searchwidget.SEARCH_ENGINE_SHORTNAME"; | 63 "org.chromium.chrome.browser.searchwidget.SEARCH_ENGINE_SHORTNAME"; |
74 static final String PREF_USE_HERB_TAB = "org.chromium.chrome.browser.searchw
idget.USE_HERB_TAB"; | 64 static final String PREF_USE_HERB_TAB = "org.chromium.chrome.browser.searchw
idget.USE_HERB_TAB"; |
75 | 65 |
76 private static final String TAG = "searchwidget"; | 66 private static final String TAG = "searchwidget"; |
77 private static final Object OBSERVER_LOCK = new Object(); | 67 private static final Object OBSERVER_LOCK = new Object(); |
78 | 68 |
79 private static SearchWidgetTemplateUrlServiceObserver sObserver; | 69 private static SearchWidgetTemplateUrlServiceObserver sObserver; |
80 private static String sCachedSearchEngineName; | 70 private static String sCachedSearchEngineName; |
81 | 71 |
(...skipping 18 matching lines...) Expand all Loading... |
100 service.load(); | 90 service.load(); |
101 } | 91 } |
102 } | 92 } |
103 updateCachedEngineName(); | 93 updateCachedEngineName(); |
104 } | 94 } |
105 | 95 |
106 @Override | 96 @Override |
107 public void onReceive(Context context, Intent intent) { | 97 public void onReceive(Context context, Intent intent) { |
108 if (IntentHandler.isIntentChromeOrFirstParty(intent)) { | 98 if (IntentHandler.isIntentChromeOrFirstParty(intent)) { |
109 if (ACTION_START_TEXT_QUERY.equals(intent.getAction())) { | 99 if (ACTION_START_TEXT_QUERY.equals(intent.getAction())) { |
110 startSearchActivity(context, intent, false); | 100 startSearchActivity(context, false); |
111 return; | 101 return; |
112 } else if (ACTION_START_VOICE_QUERY.equals(intent.getAction())) { | 102 } else if (ACTION_START_VOICE_QUERY.equals(intent.getAction())) { |
113 startSearchActivity(context, intent, true); | 103 startSearchActivity(context, true); |
114 return; | 104 return; |
115 } | 105 } |
116 } else if (ACTION_UPDATE_ALL_WIDGETS.equals(intent.getAction())) { | 106 } else if (ACTION_UPDATE_ALL_WIDGETS.equals(intent.getAction())) { |
117 performUpdate(context); | 107 performUpdate(context); |
118 return; | 108 return; |
119 } | 109 } |
120 super.onReceive(context, intent); | 110 super.onReceive(context, intent); |
121 } | 111 } |
122 | 112 |
123 private void startSearchActivity(Context context, Intent intent, boolean sta
rtVoiceSearch) { | 113 private void startSearchActivity(Context context, boolean startVoiceSearch)
{ |
124 int widgetId = getLaunchingWidgetIdFromIntent(intent); | 114 Log.d(TAG, "Launching SearchActivity: VOICE=" + startVoiceSearch); |
125 SearchWidgetProvider.setLaunchingWidgetId(widgetId); | |
126 Log.d(TAG, "Launching SearchActivity: ID=" + widgetId + " VOICE=" + star
tVoiceSearch); | |
127 | 115 |
128 // Launch the SearchActivity. | 116 // Launch the SearchActivity. |
129 Intent searchIntent = new Intent(); | 117 Intent searchIntent = new Intent(); |
130 searchIntent.setClassName(context, SearchActivity.class.getName()); | 118 searchIntent.setClassName(context, SearchActivity.class.getName()); |
131 searchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); | 119 searchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); |
132 searchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT); | 120 searchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT); |
133 searchIntent.putExtra(EXTRA_START_VOICE_SEARCH, startVoiceSearch); | 121 searchIntent.putExtra(EXTRA_START_VOICE_SEARCH, startVoiceSearch); |
134 | 122 |
135 Bundle optionsBundle; | 123 Bundle optionsBundle; |
136 if (ANIMATE_TRANSITION) { | 124 optionsBundle = |
137 // Pass the widget's bounds along to allow moving the box into place
. | 125 ActivityOptionsCompat.makeCustomAnimation(context, R.anim.activi
ty_open_enter, 0) |
138 Rect rect = intent.getSourceBounds(); | 126 .toBundle(); |
139 if (rect != null) searchIntent.setSourceBounds(rect); | |
140 optionsBundle = ActivityOptionsCompat.makeCustomAnimation(context, 0
, 0).toBundle(); | |
141 } else { | |
142 optionsBundle = ActivityOptionsCompat | |
143 .makeCustomAnimation(context, R.anim.activit
y_open_enter, 0) | |
144 .toBundle(); | |
145 } | |
146 context.startActivity(searchIntent, optionsBundle); | 127 context.startActivity(searchIntent, optionsBundle); |
147 } | 128 } |
148 | 129 |
149 @Override | 130 @Override |
150 public void onUpdate(Context context, AppWidgetManager manager, int[] ids) { | 131 public void onUpdate(Context context, AppWidgetManager manager, int[] ids) { |
151 performUpdate(context, ids); | 132 performUpdate(context, ids); |
152 super.onUpdate(context, manager, ids); | 133 super.onUpdate(context, manager, ids); |
153 } | 134 } |
154 | 135 |
155 private void performUpdate(Context context) { | 136 private void performUpdate(Context context) { |
156 AppWidgetManager manager = AppWidgetManager.getInstance(context); | 137 AppWidgetManager manager = AppWidgetManager.getInstance(context); |
157 performUpdate(context, getAllSearchWidgetIds(manager)); | 138 performUpdate(context, getAllSearchWidgetIds(manager)); |
158 } | 139 } |
159 | 140 |
160 private void performUpdate(Context context, int[] ids) { | 141 private void performUpdate(Context context, int[] ids) { |
161 for (int id : ids) updateWidget(context, id); | 142 for (int id : ids) updateWidget(context, id); |
162 } | 143 } |
163 | 144 |
164 private void updateWidget(Context context, int id) { | 145 private void updateWidget(Context context, int id) { |
165 int launchingWidgetId = ANIMATE_TRANSITION ? getLaunchingWidgetId() : IN
VALID_WIDGET_ID; | |
166 | |
167 AppWidgetManager manager = AppWidgetManager.getInstance(context); | 146 AppWidgetManager manager = AppWidgetManager.getInstance(context); |
168 RemoteViews views = new RemoteViews(context.getPackageName(), | 147 RemoteViews views = |
169 id == launchingWidgetId ? R.layout.search_widget_template_transp
arent | 148 new RemoteViews(context.getPackageName(), R.layout.search_widget
_template); |
170 : R.layout.search_widget_template); | |
171 | 149 |
172 // Clicking on the widget fires an Intent back at this BroadcastReceiver
, allowing control | 150 // Clicking on the widget fires an Intent back at this BroadcastReceiver
, allowing control |
173 // over how the Activity is animated when it starts up. | 151 // over how the Activity is animated when it starts up. |
174 Intent textIntent = createStartQueryIntent(context, ACTION_START_TEXT_QU
ERY, id); | 152 Intent textIntent = createStartQueryIntent(context, ACTION_START_TEXT_QU
ERY, id); |
175 views.setOnClickPendingIntent(R.id.text_container, | 153 views.setOnClickPendingIntent(R.id.text_container, |
176 PendingIntent.getBroadcast( | 154 PendingIntent.getBroadcast( |
177 context, 0, textIntent, PendingIntent.FLAG_UPDATE_CURREN
T)); | 155 context, 0, textIntent, PendingIntent.FLAG_UPDATE_CURREN
T)); |
178 | 156 |
179 Intent voiceIntent = createStartQueryIntent(context, ACTION_START_VOICE_
QUERY, id); | 157 Intent voiceIntent = createStartQueryIntent(context, ACTION_START_VOICE_
QUERY, id); |
180 views.setOnClickPendingIntent(R.id.microphone_icon, | 158 views.setOnClickPendingIntent(R.id.microphone_icon, |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
232 sCachedSearchEngineName = prefs.getString(PREF_SEARCH_ENGINE_SHORTNAME,
null); | 210 sCachedSearchEngineName = prefs.getString(PREF_SEARCH_ENGINE_SHORTNAME,
null); |
233 return sCachedSearchEngineName; | 211 return sCachedSearchEngineName; |
234 } | 212 } |
235 | 213 |
236 /** Get the IDs of all of Chrome's search widgets. */ | 214 /** Get the IDs of all of Chrome's search widgets. */ |
237 private static int[] getAllSearchWidgetIds(AppWidgetManager manager) { | 215 private static int[] getAllSearchWidgetIds(AppWidgetManager manager) { |
238 return manager.getAppWidgetIds(new ComponentName( | 216 return manager.getAppWidgetIds(new ComponentName( |
239 ContextUtils.getApplicationContext(), SearchWidgetProvider.class
.getName())); | 217 ContextUtils.getApplicationContext(), SearchWidgetProvider.class
.getName())); |
240 } | 218 } |
241 | 219 |
242 private int getLaunchingWidgetId() { | |
243 int launchingWidgetId = INVALID_WIDGET_ID; | |
244 | |
245 // If the SearchActivity isn't in the foreground, the user must have exi
ted it. | |
246 if (ApplicationStatus.getLastTrackedFocusedActivity() instanceof SearchA
ctivity) { | |
247 launchingWidgetId = ContextUtils.getAppSharedPreferences().getInt( | |
248 PREF_LAUNCHING_WIDGET_ID, INVALID_WIDGET_ID); | |
249 } | |
250 | |
251 return launchingWidgetId; | |
252 } | |
253 | |
254 /** Cache the ID of the widget that was used to launch the SearchActivity. *
/ | |
255 static void setLaunchingWidgetId(int id) { | |
256 SharedPreferences prefs = ContextUtils.getAppSharedPreferences(); | |
257 SharedPreferences.Editor editor = prefs.edit(); | |
258 editor.putInt(PREF_LAUNCHING_WIDGET_ID, id); | |
259 editor.apply(); | |
260 } | |
261 | |
262 /** Parse out which widget launched the Activity from the given Intent. */ | |
263 private static int getLaunchingWidgetIdFromIntent(Intent intent) { | |
264 String data = intent.getData() == null ? null : intent.getData().toStrin
g(); | |
265 if (data == null) return INVALID_WIDGET_ID; | |
266 | |
267 try { | |
268 return Integer.parseInt(data); | |
269 } catch (NumberFormatException e) { | |
270 return INVALID_WIDGET_ID; | |
271 } | |
272 } | |
273 | |
274 /** Creates a trusted Intent that lets the user begin performing queries. */ | 220 /** Creates a trusted Intent that lets the user begin performing queries. */ |
275 private Intent createStartQueryIntent(Context context, String action, int wi
dgetId) { | 221 private Intent createStartQueryIntent(Context context, String action, int wi
dgetId) { |
276 Intent intent = new Intent(action, Uri.parse(String.valueOf(widgetId))); | 222 Intent intent = new Intent(action, Uri.parse(String.valueOf(widgetId))); |
277 intent.setClass(context, getClass()); | 223 intent.setClass(context, getClass()); |
278 IntentHandler.addTrustedIntentExtras(intent); | 224 IntentHandler.addTrustedIntentExtras(intent); |
279 return intent; | 225 return intent; |
280 } | 226 } |
281 } | 227 } |
OLD | NEW |