From a680d733c864f251c31425e1e27fccd2d84d5818 Mon Sep 17 00:00:00 2001 From: Yeon Taek Jeong Date: Wed, 14 Aug 2019 16:40:21 -0700 Subject: [PATCH] For #4384: Hide mic icon if speech-to-text is unavailable (#4701) --- .../org/mozilla/fenix/SearchWidgetProvider.kt | 38 ++++++++++++++----- .../res/layout/search_widget_small_no_mic.xml | 19 ++++++++++ app/src/main/res/xml/search_widget_info.xml | 2 +- 3 files changed, 49 insertions(+), 10 deletions(-) create mode 100644 app/src/main/res/layout/search_widget_small_no_mic.xml diff --git a/app/src/main/java/org/mozilla/fenix/SearchWidgetProvider.kt b/app/src/main/java/org/mozilla/fenix/SearchWidgetProvider.kt index 34e7c6e55..9061164c1 100644 --- a/app/src/main/java/org/mozilla/fenix/SearchWidgetProvider.kt +++ b/app/src/main/java/org/mozilla/fenix/SearchWidgetProvider.kt @@ -11,6 +11,8 @@ import android.appwidget.AppWidgetProvider import android.content.Context import android.content.Intent import android.os.Bundle +import android.speech.RecognizerIntent +import android.view.View import android.widget.RemoteViews import org.mozilla.fenix.utils.Settings @@ -31,7 +33,10 @@ class SearchWidgetProvider : AppWidgetProvider() { appWidgetIds.forEach { appWidgetId -> val currentWidth = appWidgetManager.getAppWidgetOptions(appWidgetId).getInt(OPTION_APPWIDGET_MIN_WIDTH) val layoutSize = getLayoutSize(currentWidth) - val layout = getLayout(layoutSize) + // It's not enough to just hide the microphone on the "small" sized widget due to its design. + // The "small" widget needs a complete redesign, meaning it needs a new layout file. + val showMic = (voiceSearchIntent != null) + val layout = getLayout(layoutSize, showMic) val text = getText(layoutSize, context) val views = createRemoteViews(context, layout, textSearchIntent, voiceSearchIntent, text) @@ -50,7 +55,8 @@ class SearchWidgetProvider : AppWidgetProvider() { val currentWidth = appWidgetManager.getAppWidgetOptions(appWidgetId).getInt(OPTION_APPWIDGET_MIN_WIDTH) val layoutSize = getLayoutSize(currentWidth) - val layout = getLayout(layoutSize) + val showMic = (voiceSearchIntent != null) + val layout = getLayout(layoutSize, showMic) val text = getText(layoutSize, context) val views = createRemoteViews(context, layout, textSearchIntent, voiceSearchIntent, text) @@ -65,10 +71,13 @@ class SearchWidgetProvider : AppWidgetProvider() { else -> SearchWidgetProviderSize.EXTRA_SMALL_V1 } - private fun getLayout(size: SearchWidgetProviderSize) = when (size) { + private fun getLayout(size: SearchWidgetProviderSize, showMic: Boolean) = when (size) { SearchWidgetProviderSize.LARGE -> R.layout.search_widget_large SearchWidgetProviderSize.MEDIUM -> R.layout.search_widget_medium - SearchWidgetProviderSize.SMALL -> R.layout.search_widget_small + SearchWidgetProviderSize.SMALL -> { + if (showMic) R.layout.search_widget_small + else R.layout.search_widget_small_no_mic + } SearchWidgetProviderSize.EXTRA_SMALL_V2 -> R.layout.search_widget_extra_small_v2 SearchWidgetProviderSize.EXTRA_SMALL_V1 -> R.layout.search_widget_extra_small_v1 } @@ -88,26 +97,32 @@ class SearchWidgetProvider : AppWidgetProvider() { } } - private fun createVoiceSearchIntent(context: Context): PendingIntent { - return Intent(context, IntentReceiverActivity::class.java) + private fun createVoiceSearchIntent(context: Context): PendingIntent? { + val voiceIntent = Intent(context, IntentReceiverActivity::class.java) .let { intent -> intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK intent.putExtra(IntentReceiverActivity.SPEECH_PROCESSING, true) - PendingIntent.getActivity(context, REQUEST_CODE_VOICE, intent, 0) } + + val intentSpeech = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH) + + return intentSpeech.resolveActivity(context.packageManager)?.let { + PendingIntent.getActivity(context, REQUEST_CODE_VOICE, voiceIntent, 0) + } } private fun createRemoteViews( context: Context, layout: Int, textSearchIntent: PendingIntent, - voiceSearchIntent: PendingIntent, + voiceSearchIntent: PendingIntent?, text: String? ): RemoteViews { return RemoteViews(context.packageName, layout).apply { when (layout) { R.layout.search_widget_extra_small_v1, - R.layout.search_widget_extra_small_v2 -> { + R.layout.search_widget_extra_small_v2, + R.layout.search_widget_small_no_mic -> { setOnClickPendingIntent(R.id.button_search_widget_new_tab, textSearchIntent) } R.layout.search_widget_small -> { @@ -119,6 +134,11 @@ class SearchWidgetProvider : AppWidgetProvider() { setOnClickPendingIntent(R.id.button_search_widget_new_tab, textSearchIntent) setOnClickPendingIntent(R.id.button_search_widget_voice, voiceSearchIntent) setTextViewText(R.id.button_search_widget_new_tab, text) + // Unlike "small" widget, "medium" and "large" sizes do not have separate layouts + // that exclude the microphone icon, which is why we must hide it accordingly here. + if (voiceSearchIntent == null) { + this.setViewVisibility(R.id.button_search_widget_voice, View.GONE) + } } } } diff --git a/app/src/main/res/layout/search_widget_small_no_mic.xml b/app/src/main/res/layout/search_widget_small_no_mic.xml new file mode 100644 index 000000000..83fc25d20 --- /dev/null +++ b/app/src/main/res/layout/search_widget_small_no_mic.xml @@ -0,0 +1,19 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/search_widget_info.xml b/app/src/main/res/xml/search_widget_info.xml index c8d9ebbc0..ca5d940f6 100644 --- a/app/src/main/res/xml/search_widget_info.xml +++ b/app/src/main/res/xml/search_widget_info.xml @@ -9,7 +9,7 @@ android:resizeMode="horizontal" android:minResizeWidth="30dp" android:previewImage="@drawable/fenix_search_widget" - android:updatePeriodMillis="86400000" + android:updatePeriodMillis="3600000" android:initialLayout="@layout/search_widget_large" android:widgetCategory="home_screen"> \ No newline at end of file