| 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 |