/* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.quicksearchbox; import com.android.common.Search; import com.android.common.speech.Recognition; import com.android.quicksearchbox.util.Util; import android.app.Activity; import android.app.AlarmManager; import android.app.PendingIntent; import android.app.SearchManager; import android.appwidget.AppWidgetManager; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.graphics.Typeface; import android.net.Uri; import android.os.Bundle; import android.os.SystemClock; import android.speech.RecognizerIntent; import android.text.Annotation; import android.text.SpannableStringBuilder; import android.text.TextUtils; import android.text.style.StyleSpan; import android.util.Log; import android.view.View; import android.widget.RemoteViews; import java.util.ArrayList; import java.util.Random; /** * Search widget provider. * */ public class SearchWidgetProvider extends BroadcastReceiver { private static final boolean DBG = false; private static final String TAG = "QSB.SearchWidgetProvider"; /** * The {@link Search#SOURCE} value used when starting searches from the search widget. */ private static final String WIDGET_SEARCH_SOURCE = "launcher-widget"; @Override public void onReceive(Context context, Intent intent) { if (DBG) Log.d(TAG, "onReceive(" + intent.toUri(0) + ")"); String action = intent.getAction(); if (AppWidgetManager.ACTION_APPWIDGET_ENABLED.equals(action)) { // nothing needs doing } else if (AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) { updateSearchWidgets(context); } else { if (DBG) Log.d(TAG, "Unhandled intent action=" + action); } } private static SearchWidgetState[] getSearchWidgetStates(Context context) { AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); int[] appWidgetIds = appWidgetManager.getAppWidgetIds(myComponentName(context)); SearchWidgetState[] states = new SearchWidgetState[appWidgetIds.length]; for (int i = 0; i<appWidgetIds.length; ++i) { states[i] = getSearchWidgetState(context, appWidgetIds[i]); } return states; } /** * Updates all search widgets. */ public static void updateSearchWidgets(Context context) { if (DBG) Log.d(TAG, "updateSearchWidgets"); SearchWidgetState[] states = getSearchWidgetStates(context); for (SearchWidgetState state : states) { state.updateWidget(context, AppWidgetManager.getInstance(context)); } } /** * Gets the component name of this search widget provider. */ private static ComponentName myComponentName(Context context) { String pkg = context.getPackageName(); String cls = pkg + ".SearchWidgetProvider"; return new ComponentName(pkg, cls); } private static Intent createQsbActivityIntent(Context context, String action, Bundle widgetAppData) { Intent qsbIntent = new Intent(action); qsbIntent.setPackage(context.getPackageName()); qsbIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); qsbIntent.putExtra(SearchManager.APP_DATA, widgetAppData); return qsbIntent; } private static SearchWidgetState getSearchWidgetState(Context context, int appWidgetId) { if (DBG) Log.d(TAG, "Creating appwidget state " + appWidgetId); SearchWidgetState state = new SearchWidgetState(appWidgetId); Bundle widgetAppData = new Bundle(); widgetAppData.putString(Search.SOURCE, WIDGET_SEARCH_SOURCE); // Text field click Intent qsbIntent = createQsbActivityIntent( context, SearchManager.INTENT_ACTION_GLOBAL_SEARCH, widgetAppData); state.setQueryTextViewIntent(qsbIntent); // Voice search button Intent voiceSearchIntent = getVoiceSearchIntent(context, widgetAppData); state.setVoiceSearchIntent(voiceSearchIntent); return state; } private static Intent getVoiceSearchIntent(Context context, Bundle widgetAppData) { VoiceSearch voiceSearch = QsbApplication.get(context).getVoiceSearch(); return voiceSearch.createVoiceWebSearchIntent(widgetAppData); } private static class SearchWidgetState { private final int mAppWidgetId; private Intent mCorpusIndicatorIntent; private Intent mQueryTextViewIntent; private Intent mVoiceSearchIntent; public SearchWidgetState(int appWidgetId) { mAppWidgetId = appWidgetId; } public void setQueryTextViewIntent(Intent queryTextViewIntent) { mQueryTextViewIntent = queryTextViewIntent; } public void setVoiceSearchIntent(Intent voiceSearchIntent) { mVoiceSearchIntent = voiceSearchIntent; } public void updateWidget(Context context,AppWidgetManager appWidgetMgr) { if (DBG) Log.d(TAG, "Updating appwidget " + mAppWidgetId); RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.search_widget); // // Corpus indicator setOnClickActivityIntent(context, views, R.id.search_icon, mCorpusIndicatorIntent); setOnClickActivityIntent(context, views, R.id.search_widget_text, mQueryTextViewIntent); // Voice Search button if (mVoiceSearchIntent != null) { setOnClickActivityIntent(context, views, R.id.search_widget_voice_btn, mVoiceSearchIntent); views.setViewVisibility(R.id.search_widget_voice_btn, View.VISIBLE); } else { views.setViewVisibility(R.id.search_widget_voice_btn, View.GONE); } appWidgetMgr.updateAppWidget(mAppWidgetId, views); } private void setOnClickActivityIntent(Context context, RemoteViews views, int viewId, Intent intent) { PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0); views.setOnClickPendingIntent(viewId, pendingIntent); } } }