Bug 1035642 - Add search widget. r=mfinkle,margaret

This commit is contained in:
Wes Johnston 2014-07-30 14:47:00 -07:00
parent 879108f360
commit 9088d96204
18 changed files with 257 additions and 1 deletions

View File

@ -0,0 +1,124 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
* 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.search;
import org.mozilla.gecko.AppConstants;
import android.annotation.SuppressLint;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.widget.RemoteViews;
import android.util.Log;
/* Provides a really simple widget with two buttons, one to launch Fennec
* and one to launch the search activity. All intents are actually sent back
* here and then forwarded on to start the real activity. */
public class SearchWidget extends AppWidgetProvider {
final private static String LOGTAG = "GeckoSearchWidget";
final public static String ACTION_LAUNCH_BROWSER = "org.mozilla.widget.LAUNCH_BROWSER";
final public static String ACTION_LAUNCH_SEARCH = "org.mozilla.widget.LAUNCH_SEARCH";
@SuppressLint("NewApi")
@Override
public void onUpdate(final Context context, final AppWidgetManager manager, final int[] ids) {
for (int id : ids) {
final Bundle bundle;
if (AppConstants.Versions.feature16Plus) {
bundle = manager.getAppWidgetOptions(id);
} else {
bundle = null;
}
addView(manager, context, id, bundle);
}
super.onUpdate(context, manager, ids);
}
@SuppressLint("NewApi")
@Override
public void onAppWidgetOptionsChanged(final Context context,
final AppWidgetManager manager,
final int id,
final Bundle options) {
addView(manager, context, id, options);
if (AppConstants.Versions.feature16Plus) {
super.onAppWidgetOptionsChanged(context, manager, id, options);
}
}
@Override
public void onReceive(final Context context, final Intent intent) {
// This will hold the intent to redispatch
final Intent redirect;
Log.i(LOGTAG, "Got intent " + intent.getAction());
if (intent.getAction().equals(ACTION_LAUNCH_BROWSER)) {
redirect = buildRedirectIntent(Intent.ACTION_VIEW,
AppConstants.ANDROID_PACKAGE_NAME,
AppConstants.BROWSER_INTENT_CLASS_NAME,
intent);
} else if (intent.getAction().equals(ACTION_LAUNCH_SEARCH)) {
redirect = buildRedirectIntent(Intent.ACTION_VIEW,
AppConstants.SEARCH_PACKAGE_NAME,
AppConstants.SEARCH_INTENT_CLASS_NAME,
intent);
} else {
redirect = null;
}
if (redirect != null) {
try {
context.startActivity(redirect);
} catch(Exception ex) {
// When this is built stand alone, its hardcoded to try and launch nightly.
// If that fails, just fire a generic VIEW intent.
Intent redirect2 = buildRedirectIntent(Intent.ACTION_VIEW, null, null, intent);
context.startActivity(redirect2);
}
}
super.onReceive(context, intent);
}
// Utility to create the view for this widget and attach any event listeners to it
private void addView(final AppWidgetManager manager, final Context context, final int id, final Bundle options) {
final RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.search_widget);
addClickIntent(context, views, R.id.search_button, ACTION_LAUNCH_SEARCH);
addClickIntent(context, views, R.id.new_tab_button, ACTION_LAUNCH_BROWSER);
// Clicking the logo also launches the browser
addClickIntent(context, views, R.id.logo_button, ACTION_LAUNCH_BROWSER);
manager.updateAppWidget(id, views);
}
// Utility for adding a pending intent to be fired when a View is clicked.
private void addClickIntent(final Context context, final RemoteViews views, final int viewId, final String action) {
final Intent intent = new Intent(context, SearchWidget.class);
intent.setAction(action);
intent.setData(Uri.parse("about:home"));
final PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
views.setOnClickPendingIntent(viewId, pendingIntent);
}
// Utility for building an intent to be redispatched (i.e. to launch the browser or the search intent).
private Intent buildRedirectIntent(final String action, final String pkg, final String className, final Intent source) {
final Intent activity = new Intent(action);
if (pkg != null && className != null) {
activity.setClassName(pkg, className);
}
activity.setData(source.getData());
activity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
return activity;
}
}

View File

@ -13,8 +13,28 @@
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<!-- Basic launcher widget. -->
<receiver android:name="org.mozilla.search.SearchWidget"
android:label="@string/search_widget_name">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<intent-filter>
<action android:name="org.mozilla.widget.LAUNCH_BROWSER"/>
</intent-filter>
<intent-filter>
<action android:name="org.mozilla.widget.LAUNCH_SEARCH"/>
</intent-filter>
<meta-data android:name="android.appwidget.provider" android:resource="@xml/search_widget_info" />
</receiver>
<activity
android:name="org.mozilla.search.SearchPreferenceActivity"
android:label="@string/search_pref_title"

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -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/. -->
<!-- Drawable used for buttons in the launch widget -->
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:constantSize="true">
<item android:state_pressed="true"
android:drawable="@drawable/widget_active_bg"/>
<item android:drawable="@drawable/widget_bg"/>
</selector>

View File

@ -0,0 +1,71 @@
<?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/. -->
<!-- A homescreen widget for launching Fennec or the search activity. We can't use styles in here
so make sure any changes you make are also made to launch_widget.xml which doesn't have
the search widget button. -->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="@dimen/widget_header_height">
<!-- Wrap in a linear layout to center the text in a flexible space. We use a negative margin
to extend this into the firefox logo so that the button background appears to come from behind the logo, but
highlights correctly when tapped. -->
<LinearLayout android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toLeftOf="@+id/logo_button"
android:layout_marginRight="@dimen/widget_button_offset"
android:paddingRight="@dimen/widget_button_padding"
android:gravity="center"
android:background="@drawable/search_widget_button"
android:orientation="horizontal"
android:id="@+id/search_button">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="@drawable/ic_url_bar_search"
android:drawablePadding="@dimen/widget_drawable_padding"
android:text="@string/search_widget_button_label"
android:contentDescription="@string/search_widget_button_label"
android:gravity="center"
android:textSize="@dimen/widget_text_size"
android:textColor="@color/text_color_primary"
android:id="@+id/search_button_label"/>
</LinearLayout>
<LinearLayout android:layout_width="match_parent"
android:layout_toRightOf="@+id/logo_button"
android:layout_height="match_parent"
android:layout_marginLeft="@dimen/widget_button_offset"
android:paddingLeft="@dimen/widget_button_padding"
android:layout_centerVertical="true"
android:gravity="center"
android:background="@drawable/search_widget_button"
android:orientation="horizontal"
android:id="@+id/new_tab_button">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="@drawable/ic_widget_new_tab"
android:drawablePadding="@dimen/widget_drawable_padding"
android:gravity="center"
android:text="@string/new_tab"
android:contentDescription="@string/new_tab"
android:textSize="@dimen/widget_text_size"
android:textColor="@color/text_color_primary"
android:id="@+id/new_tab_button_label"/>
</LinearLayout>
<!-- The logo. adjustViewBounds is required for the buttons above to stretch underneath the logo. -->
<ImageView android:id="@+id/logo_button"
android:layout_centerInParent="true"
android:adjustViewBounds="true"
android:layout_width="@dimen/widget_header_height"
android:layout_height="match_parent"
android:src="@drawable/icon"/>
</RelativeLayout>

View File

@ -23,4 +23,11 @@
<dimen name="card_padding_x">38dp</dimen>
<dimen name="card_padding_y">23dp</dimen>
<!-- Widget Buttons -->
<dimen name="widget_header_height">70dp</dimen>
<dimen name="widget_button_offset">-50dp</dimen>
<dimen name="widget_button_padding">45dp</dimen>
<dimen name="widget_text_size">15sp</dimen>
<dimen name="widget_drawable_padding">2dp</dimen>
</resources>

View File

@ -0,0 +1,12 @@
<?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="300dp"
android:minHeight="40dp"
android:label="@string/search_widget_name"
android:widgetCategory="home_screen"
android:previewImage="@drawable/launcher_widget"
android:initialLayout="@layout/search_widget"/>

View File

@ -16,4 +16,5 @@ search_activity_sources = [
'java/org/mozilla/search/PostSearchFragment.java',
'java/org/mozilla/search/PreSearchFragment.java',
'java/org/mozilla/search/SearchPreferenceActivity.java',
'java/org/mozilla/search/SearchWidget.java',
]

View File

@ -4,7 +4,7 @@
<!ENTITY search_jump_arrow '&#8598;'>
<!ENTITY search_app_name 'Firefox Search'>
<!ENTITY search_app_name '&brandShortName; Search'>
<!ENTITY search_for_something 'Search for something'>
<!ENTITY search_pref_title 'Settings'>
@ -12,3 +12,6 @@
<!ENTITY search_pref_clear_history_dialog_message 'Delete all search history from this device?'>
<!ENTITY search_pref_clear_history_title 'Clear search history'>
<!ENTITY search_pref_button_content_description 'Settings'>
<!ENTITY search_widget_button_label 'Search'>

View File

@ -8,3 +8,6 @@
<string name="search_pref_clear_history_dialog_message">&search_pref_clear_history_dialog_message;</string>
<string name="search_pref_clear_history_title">&search_pref_clear_history_title;</string>
<string name="search_pref_button_content_description">&search_pref_button_content_description;</string>
<string name="search_widget_name">&search_app_name;</string>
<string name="search_widget_button_label">&search_widget_button_label;</string>