[fenix] For https://github.com/mozilla-mobile/fenix/issues/201: Search Widget
parent
99f4186812
commit
04d9c346f5
@ -0,0 +1,136 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.fenix
|
||||
|
||||
import android.app.PendingIntent
|
||||
import android.appwidget.AppWidgetManager
|
||||
import android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH
|
||||
import android.appwidget.AppWidgetProvider
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.widget.RemoteViews
|
||||
|
||||
class SearchWidgetProvider : AppWidgetProvider() {
|
||||
|
||||
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
|
||||
val textSearchIntent = createTextSearchIntent(context)
|
||||
val voiceSearchIntent = createVoiceSearchIntent(context)
|
||||
|
||||
appWidgetIds.forEach { appWidgetId ->
|
||||
val currentWidth = appWidgetManager.getAppWidgetOptions(appWidgetId).getInt(OPTION_APPWIDGET_MIN_WIDTH)
|
||||
val layoutSize = getLayoutSize(currentWidth)
|
||||
val layout = getLayout(layoutSize)
|
||||
val text = getText(layoutSize, context)
|
||||
|
||||
val views = createRemoteViews(context, layout, textSearchIntent, voiceSearchIntent, text)
|
||||
appWidgetManager.updateAppWidget(appWidgetId, views)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onAppWidgetOptionsChanged(
|
||||
context: Context,
|
||||
appWidgetManager: AppWidgetManager,
|
||||
appWidgetId: Int,
|
||||
newOptions: Bundle?
|
||||
) {
|
||||
val textSearchIntent = createTextSearchIntent(context)
|
||||
val voiceSearchIntent = createVoiceSearchIntent(context)
|
||||
|
||||
val currentWidth = appWidgetManager.getAppWidgetOptions(appWidgetId).getInt(OPTION_APPWIDGET_MIN_WIDTH)
|
||||
val layoutSize = getLayoutSize(currentWidth)
|
||||
val layout = getLayout(layoutSize)
|
||||
val text = getText(layoutSize, context)
|
||||
|
||||
val views = createRemoteViews(context, layout, textSearchIntent, voiceSearchIntent, text)
|
||||
appWidgetManager.updateAppWidget(appWidgetId, views)
|
||||
}
|
||||
|
||||
private fun getLayoutSize(dp: Int) = when {
|
||||
dp >= DP_EXTRA_LARGE -> SearchWidgetProviderSize.EXTRA_LARGE
|
||||
dp >= DP_LARGE -> SearchWidgetProviderSize.LARGE
|
||||
dp >= DP_MEDIUM -> SearchWidgetProviderSize.MEDIUM
|
||||
dp >= DP_SMALL -> SearchWidgetProviderSize.SMALL
|
||||
else -> SearchWidgetProviderSize.EXTRA_SMALL
|
||||
}
|
||||
|
||||
private fun getLayout(size: SearchWidgetProviderSize) = when (size) {
|
||||
SearchWidgetProviderSize.EXTRA_LARGE -> R.layout.search_widget_extra_large
|
||||
SearchWidgetProviderSize.LARGE -> R.layout.search_widget_large
|
||||
SearchWidgetProviderSize.MEDIUM -> R.layout.search_widget_medium
|
||||
SearchWidgetProviderSize.SMALL -> R.layout.search_widget_small
|
||||
SearchWidgetProviderSize.EXTRA_SMALL -> R.layout.search_widget_extra_small
|
||||
}
|
||||
|
||||
private fun getText(layout: SearchWidgetProviderSize, context: Context) = when (layout) {
|
||||
SearchWidgetProviderSize.MEDIUM -> context.getString(R.string.search_widget_text_short)
|
||||
SearchWidgetProviderSize.LARGE,
|
||||
SearchWidgetProviderSize.EXTRA_LARGE -> context.getString(R.string.search_widget_text_long)
|
||||
else -> null
|
||||
}
|
||||
|
||||
private fun createTextSearchIntent(context: Context): PendingIntent {
|
||||
return Intent(context, HomeActivity::class.java)
|
||||
.let { intent ->
|
||||
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
|
||||
intent.putExtra(HomeActivity.OPEN_TO_SEARCH, true)
|
||||
PendingIntent.getActivity(context, REQUEST_CODE_NEW_TAB, intent, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createVoiceSearchIntent(context: Context): PendingIntent {
|
||||
return 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)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createRemoteViews(
|
||||
context: Context,
|
||||
layout: Int,
|
||||
textSearchIntent: PendingIntent,
|
||||
voiceSearchIntent: PendingIntent,
|
||||
text: String?
|
||||
): RemoteViews {
|
||||
return RemoteViews(context.packageName, layout).apply {
|
||||
when (layout) {
|
||||
R.layout.search_widget_extra_small -> {
|
||||
setOnClickPendingIntent(R.id.button_search_widget_new_tab, textSearchIntent)
|
||||
}
|
||||
R.layout.search_widget_small -> {
|
||||
setOnClickPendingIntent(R.id.button_search_widget_new_tab, textSearchIntent)
|
||||
setOnClickPendingIntent(R.id.button_search_widget_voice, voiceSearchIntent)
|
||||
}
|
||||
R.layout.search_widget_medium,
|
||||
R.layout.search_widget_large,
|
||||
R.layout.search_widget_extra_large -> {
|
||||
setOnClickPendingIntent(R.id.button_search_widget_new_tab, textSearchIntent)
|
||||
setOnClickPendingIntent(R.id.button_search_widget_voice, voiceSearchIntent)
|
||||
setTextViewText(R.id.text_search_widget, text)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Cell sizes obtained from the actual dimensions listed in search widget specs
|
||||
companion object {
|
||||
private const val DP_SMALL = 100
|
||||
private const val DP_MEDIUM = 192
|
||||
private const val DP_LARGE = 256
|
||||
private const val DP_EXTRA_LARGE = 360
|
||||
private const val REQUEST_CODE_NEW_TAB = 0
|
||||
private const val REQUEST_CODE_VOICE = 1
|
||||
}
|
||||
}
|
||||
|
||||
enum class SearchWidgetProviderSize {
|
||||
EXTRA_SMALL,
|
||||
SMALL,
|
||||
MEDIUM,
|
||||
LARGE,
|
||||
EXTRA_LARGE
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 37 KiB |
File diff suppressed because one or more lines are too long
@ -0,0 +1,8 @@
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
<vector android:height="32dp" android:viewportHeight="24"
|
||||
android:viewportWidth="24" android:width="32dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#FF000000" android:fillType="evenOdd" android:pathData="M17,11v-1a1,1 0,0 1,2 0v1a7,7 0,0 1,-6 6.93L13,21a1,1 0,0 1,-2 0v-3.07A7,7 0,0 1,5 11v-1a1,1 0,0 1,2 0v1a5,5 0,0 0,10 0zM12,2a3,3 0,0 1,3 3v6a3,3 0,0 1,-6 0L9,5a3,3 0,0 1,3 -3z"/>
|
||||
</vector>
|
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="@color/white_color" />
|
||||
<corners android:radius="@dimen/tab_corner_radius"/>
|
||||
</shape>
|
@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<RelativeLayout android:layout_width="360dp"
|
||||
android:layout_height="50dp"
|
||||
android:background="@drawable/rounded_white_corners"
|
||||
android:layout_gravity="center">
|
||||
|
||||
<LinearLayout android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="9dp"
|
||||
android:id="@+id/button_search_widget_new_tab">
|
||||
<ImageView
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:background="@drawable/ic_logo_widget"
|
||||
android:layout_marginLeft="9dp"
|
||||
android:layout_marginRight="12dp"/>
|
||||
<TextView
|
||||
android:id="@+id/text_search_widget"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="32dp"
|
||||
android:gravity="center"
|
||||
android:textSize="15dp"
|
||||
android:textColor="@color/search_widget_text"
|
||||
android:letterSpacing="-0.025"/>
|
||||
</LinearLayout>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/button_search_widget_voice"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:background="@drawable/ic_microphone_widget"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignTop="@id/button_search_widget_new_tab"
|
||||
android:layout_marginRight="9dp"/>
|
||||
</RelativeLayout>
|
||||
|
||||
</FrameLayout>
|
@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout android:layout_width="64dp"
|
||||
android:layout_height="50dp"
|
||||
android:background="@drawable/rounded_white_corners"
|
||||
android:layout_gravity="center"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageButton
|
||||
android:id="@id/button_search_widget_new_tab"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:background="@drawable/ic_logo_widget"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="5dp"/>
|
||||
</LinearLayout>
|
||||
|
||||
</FrameLayout>
|
@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<RelativeLayout android:layout_width="256dp"
|
||||
android:layout_height="50dp"
|
||||
android:background="@drawable/rounded_white_corners"
|
||||
android:layout_gravity="center">
|
||||
|
||||
<LinearLayout android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="9dp"
|
||||
android:id="@+id/button_search_widget_new_tab">
|
||||
<ImageView
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:background="@drawable/ic_logo_widget"
|
||||
android:layout_marginLeft="9dp"
|
||||
android:layout_marginRight="12dp"/>
|
||||
<TextView
|
||||
android:id="@+id/text_search_widget"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="32dp"
|
||||
android:gravity="center"
|
||||
android:textSize="15dp"
|
||||
android:textColor="@color/search_widget_text"
|
||||
android:letterSpacing="-0.025"/>
|
||||
</LinearLayout>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/button_search_widget_voice"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:background="@drawable/ic_microphone_widget"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignTop="@id/button_search_widget_new_tab"
|
||||
android:layout_marginRight="9dp"/>
|
||||
</RelativeLayout>
|
||||
|
||||
</FrameLayout>
|
@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<RelativeLayout android:layout_width="192dp"
|
||||
android:layout_height="50dp"
|
||||
android:background="@drawable/rounded_white_corners"
|
||||
android:layout_gravity="center">
|
||||
|
||||
<LinearLayout android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="9dp"
|
||||
android:id="@+id/button_search_widget_new_tab">
|
||||
<ImageView
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:background="@drawable/ic_logo_widget"
|
||||
android:layout_marginLeft="9dp"
|
||||
android:layout_marginRight="12dp"/>
|
||||
<TextView
|
||||
android:id="@+id/text_search_widget"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="32dp"
|
||||
android:gravity="center"
|
||||
android:textSize="15dp"
|
||||
android:textColor="@color/search_widget_text"
|
||||
android:letterSpacing="-0.025"/>
|
||||
</LinearLayout>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/button_search_widget_voice"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:background="@drawable/ic_microphone_widget"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignTop="@id/button_search_widget_new_tab"
|
||||
android:layout_marginRight="9dp"/>
|
||||
</RelativeLayout>
|
||||
|
||||
</FrameLayout>
|
@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<RelativeLayout android:layout_width="100dp"
|
||||
android:layout_height="50dp"
|
||||
android:background="@drawable/rounded_white_corners"
|
||||
android:layout_gravity="center">
|
||||
|
||||
<LinearLayout android:id="@+id/button_search_widget_new_tab"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="9dp">
|
||||
<ImageView
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:background="@drawable/ic_logo_widget"
|
||||
android:layout_marginLeft="9dp"
|
||||
android:layout_marginRight="12dp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/button_search_widget_voice"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:background="@drawable/ic_microphone_widget"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignTop="@id/button_search_widget_new_tab"
|
||||
android:layout_marginRight="9dp"/>
|
||||
</RelativeLayout>
|
||||
|
||||
</FrameLayout>
|
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:minWidth="256dp"
|
||||
android:minHeight="50dp"
|
||||
android:resizeMode="horizontal"
|
||||
android:minResizeWidth="30dp"
|
||||
android:previewImage="@drawable/fenix_search_widget"
|
||||
android:updatePeriodMillis="86400000"
|
||||
android:initialLayout="@layout/search_widget_large"
|
||||
android:widgetCategory="home_screen">
|
||||
</appwidget-provider>
|
Loading…
Reference in New Issue